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
Related
I wrote a code in the Android project that uploads a file with a specific name and address to the server. But ProgressBar does not work well and does not show progress and file upload percentage. But the file upload works well and is located on the server. Now I want to show the percentage of progress in the Progress bar when uploading the file to the server to determine how much of the file has been uploaded to the server.
I tried to do this with AsyncTask.
My code ...
private class UploadTask extends AsyncTask<String, Integer, String> {
private final Context context;
public UploadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
wl.acquire(10 * 60 * 1000L /*10 minutes*/);
try {
String fileName = uploadFilePath + uploadFileName;
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(uploadFilePath + uploadFileName);
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :"
+ uploadFilePath + "" + uploadFileName);
getActivity().runOnUiThread(new Runnable() {
#SuppressLint("SetTextI18n")
public void run() {
messageText.setText("Source File not exist :"
+ uploadFilePath + "" + uploadFileName);
}
});
Sneaker.with(getActivity())
.setTitle("Error !")
.setMessage("Source File not exist")
.sneakError();
} else {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
// URL url = new URL(upLoadServerUri);
URL url = new URL(sUrl[0]);
// 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);
String name = key_login_userid + ".JM";
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + name + "\"" + 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);
long total = 0;
while (bytesRead > 0) {
total++;
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
publishProgress((int) (bufferSize * 100 / maxBufferSize));
}
// 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) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
messageText.setText("");
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
getActivity().runOnUiThread(new Runnable() {
#SuppressLint("SetTextI18n")
public void run() {
messageText.setText("MalformedURLException Exception : check script url.");
Sneaker.with(getActivity())
.setTitle("Error !")
.setMessage("MalformedURLException")
.sneakError();
}
});
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
getActivity().runOnUiThread(new Runnable() {
#SuppressLint("SetTextI18n")
public void run() {
messageText.setText("Got Exception : see logcat ");
Sneaker.with(getActivity())
.setTitle("Error !")
.setMessage("Got Exception : see logcat")
.sneakError();
}
});
Log.e("Upload file to server Exception", "Exception : "
+ e.getMessage(), e);
}
dialog.dismiss();
} // End else block
} finally {
wl.release();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
dialog.setIndeterminate(false);
dialog.setMax(100);
dialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
if (result != null) {
Sneaker.with(getActivity())
.setTitle("خطا !")
.setMessage("خطا در ارسال اطلاعات.")
.sneakError();
} else {
Sneaker.with(getActivity())
.setTitle("توجه!")
.setMessage("ارسال اطلاعات کامل شد.")
.sneakSuccess();
}
}
}
You can use this code to show progress bar when using Asynctask
https://www.concretepage.com/android/android-asynctask-example-with-progress-bar
I have the following file upload function:
public void uploadFile(Context context, File file) {
String urlServer = "https://u-database.000webhostapp.com/recieve_file.php";
if(file.isFile() && file.exists()) {
String fileName = file.getAbsolutePath();
try {
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;
Toast toastw = Toast.makeText(context, "Inside TRY", Toast.LENGTH_SHORT);
toastw.show();
FileInputStream fileInputStream = new FileInputStream(file);
URL url = new URL(urlServer);
// 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("textLog", fileName);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"textLog\";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)
int serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Toast toast = Toast.makeText(context, "Uploading", Toast.LENGTH_SHORT);
toast.show();
if(serverResponseCode == 200){
file.delete();
Toast toasto = Toast.makeText(context, "success", Toast.LENGTH_SHORT);
toasto.show();
}
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
Toast toast = Toast.makeText(context, "Malformed URL", Toast.LENGTH_SHORT);
toast.show();
} catch (Exception e) {
Toast toast = Toast.makeText(context, "Exception", Toast.LENGTH_SHORT);
toast.show();
}
}
}
Each time it is executed, a toast appears stating Inside TRY and then another appears stating "Exception".
I have been debugging a lot and any kind of help would be really appreciated :)
UPDATE
When I did e.toString and printed it out to a toast, I got: android.os.NetworkOnMainThreadException
The answer is simple then. You should run your network calls on a background thread. You need to extend AsyncTask and move your code into it. Something like:
private class InitTask extends AsyncTask<Void, Void, Void>{
protected Void doInBackground(Void... p){
// Call upload file code here
}
}
I am trying to upload large video files to the server. I wrote a piece of code which works well for the image so I thought I should work it for the video too.
I wrote the below code.
public int uploadFile(String sourceFileUri) {
String fileName = sourceFileUri;
//Log.v("ONMESSAGE", "File type is " + filetype + "File name is " + fileName);
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();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(GcmActivity.this, "File not found", Toast.LENGTH_LONG).show();
}
});
return 0;
}
else
{
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL("http://example.com/ccs-business/upload.php");
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
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("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName +"\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);//1
buffer = new byte[bufferSize];//2
bytesRead = fileInputStream.read(buffer, 0, bufferSize); //3
while (bytesRead > 0) { //4
dos.write(buffer, 0, bufferSize);//5
bytesAvailable = fileInputStream.available();//6
bufferSize = Math.min(bytesAvailable, maxBufferSize);//7
bytesRead = fileInputStream.read(buffer, 0, bufferSize);//8
}//9
// 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() {
Toast.makeText(GcmActivity.this, "File Upload Complete.",
Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
}
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(GcmActivity.this, "MalformedURLException",
Toast.LENGTH_SHORT).show();
}
});
Log.v("ONMESSAGE", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(GcmActivity.this, "Got Exception : see logcat ",
Toast.LENGTH_SHORT).show();
}
});
Log.v("ONMESSAGE", "Exception : "
+ e.getMessage(), e);
}
dialog.dismiss();
return serverResponseCode;
} // End else block
}
This piece of code gives me java.lang.OutOfMemory error so I followed other's suggestion and added a key to manifest that is largeheap, did not work. so I followed other suggestion and changed the code to below
public int uploadFileVideo(String sourceFileUri) {
String fileName = sourceFileUri;
//Log.v("ONMESSAGE", "File type is " + filetype + "File name is " + fileName);
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();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(GcmActivity.this, "File not found", Toast.LENGTH_LONG).show();
}
});
return 0;
}
else
{
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL("http://example.com/ccs-business/upload.php");
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
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_video", 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("Content-Disposition: form-data; name=\"uploaded_video\";filename=\"" + fileName +"\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
/* bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize); */
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
byte byt[]=new byte[bufferSize];
fileInputStream.read(byt);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
dos.write(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() {
Toast.makeText(GcmActivity.this, "File Upload Complete.",
Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
}
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(GcmActivity.this, "MalformedURLException",
Toast.LENGTH_SHORT).show();
}
});
Log.v("ONMESSAGE", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(GcmActivity.this, "Got Exception : see logcat ",
Toast.LENGTH_SHORT).show();
}
});
Log.v("ONMESSAGE", "Exception : "
+ e.getMessage(), e);
}
dialog.dismiss();
return serverResponseCode;
} // End else block
}
Now files gets uploaded however all file size of 1 MB and that too can not be played.
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
byte byt[]=new byte[bufferSize];
fileInputStream.read(byt);
You are not writing the bytes read into byt out to the outputstream. Removing the first read into byt should fix a problem. But you will come across another problem where a file over 1MB only the first 1MB will be uploaded.
A proper way to copy a stream is to do something similar to
byte[] buf = new byte[ 1024 ];
int read = 0;
while( ( read = in.read( buf ) ) != -1 ) {
out.write( buf, 0, read );
}
avoid buffering the whole POST data in RAM by adding conn.setChunkedStreamingMode(0); after : con.setDoOutput(true);
hope this help :)
I'm trying to design an application that starts a camera intent, uploads a photo, (and hopefully, work in progress: parse an XML response from the server, then move to another activity and fill in some form fields).
The problem is that so far the upload code is executed the 1st time I run the application, the 2nd time it gets skipped, the 3rd time works fine, 4th skips and so on.
MainActivity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// buttons
Button lunchCamBtn = (Button) findViewById(R.id.lunchVerBtn);
lunchCamBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
}
});
Button lunchCaptBtn = (Button) findViewById(R.id.lunchCaptBtn);
lunchCaptBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
dispatchTakePictureIntent();
}
});
}
String path;
String picfname;
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
Random rnd = new Random(System.currentTimeMillis());
DateFormat dateFormat = new SimpleDateFormat("ddMMyyyy");
Date date = new Date();
String picfname = "bul "+dateFormat.format(date)+" "+rnd.nextInt(90)+".png";
File output = new File(dir,picfname);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(output));
path = output.getAbsolutePath();
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(getApplicationContext(), path.toString(),
Toast.LENGTH_LONG).show();
UploadFiles upld =new UploadFiles(MainActivity.this);
upld.execute(path.toString());
}
UploadFiles:
public class UploadFiles extends AsyncTask<String, Integer, Boolean> {
WeakReference<Activity> mActivityReference;
public UploadFiles(Activity activity){
this.mActivityReference = new WeakReference<Activity>(activity);
}
#Override
protected Boolean doInBackground(String... params) {
Boolean succesz = true;
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
DataInputStream inputStream = null;
String selectedPath = params[0];
String pathToOurFile = selectedPath;
String urlServer = "http://192.168.0.104/upload2.php";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
try {
Bitmap bmp = BitmapFactory.decodeFile(pathToOurFile);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 90, bos);
InputStream fileInputStream = new ByteArrayInputStream(bos.toByteArray());
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setChunkedStreamingMode(1024);
connection.setReadTimeout(25000 /* milliseconds */);
connection.setConnectTimeout(30000 /* milliseconds */);
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=\"uploadedfile\";filename=\""
+ pathToOurFile + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
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);
InputStream stream = connection.getInputStream();
InputStreamReader isReader = new InputStreamReader(stream);
String line = "";
line = convertStreamToString(stream);
System.out.print(line);
fileInputStream.close();
outputStream.flush();
outputStream.close();
} catch (Exception ex) {
}
return succesz;
}
private String convertStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (Exception e) {
//Toast.makeText(this, "Stream Exception", Toast.LENGTH_SHORT).show();
}
return total.toString();
}
#Override
protected void onPostExecute(Boolean result) {
if (result && mActivityReference.get() != null) {
Activity activity = mActivityReference.get();
Intent iinent= new Intent(activity,TestActivity.class);
activity.startActivity(iinent);
//activity.finish();
}
}}
I know now that this issue is caused by the convertStreamToString method in class UploadFiles but I can't understand what exactly causes it. When I remove it completely everything works fine. Thank you in advance!
The first minor problem:
Using available is basically wrong, though it might work.
The second minor problem:
Do not use DataOutputStream here. I guess it is done to be able to write Strings to an OutputStream.
response.setContentType("...; charset=Windows-1252");
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(os, "Windows-1252"));
Somehow also specifying the encoding/charset may help.
Problem with the convertStreamToString:
In no extra encoding parameter is added to the InputStreamReader, the default platform encoding is used. UTF-8 on Android. That would fail relatively fast.
You might give a less strict single-byte encoding a try to see what happens:
BufferedReader rd = new BufferedReader(new InputStreamReader(is, "Windows-1252"));
In general encoding is not handled: URLConnection.getContentEncoding() maybe is informative.
You are doing couple of things wrong here.
Don't leave exception blocks empty. It hides all the error. Use Log.e to print that.
Don't use System.out.println. Use Log.* only for logging.
Don't use AsyncTask to upload your file. Use IntentService Instead. And using localbroadcastmanager broadcast upload events for your activity to listen. It will be more configuration change friendly.
Instead of doing all this file upload sorcery yourself. Use httpmime library instead. It works simply awesome on android. I have my apps on production using this. Something like this you have to do.
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlToUpload);
MultipartEntity entity = new MultipartEntity();
Bitmap bmp = BitmapFactory.decodeFile(sourceFileUri);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 50, bos);
InputStream in = new ByteArrayInputStream(bos.toByteArray());
ContentBody imageContent = new InputStreamBody(in, "image/jpeg", sourceFile.getName());
entity.addPart("file", imageContent);
post.setEntity(entity);
HttpResponse response = client.execute(post);
You will have your everything in 'response' for you to read.
String responseBody = EntityUtils.toString(response.getEntity());
From here you can download this library http://repo1.maven.org/maven2/org/apache/httpcomponents/httpmime/4.2.5/
I have used this https://github.com/alexbbb/android-upload-service for file uploads.
I handle all the response-related logic inside the Broadcast receiver, where I'm waiting for the upload responses.
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.