16306

Trying to use Async with image upload to webserver android?

Question:

I am trying to use Async to be more efficient and to allow for image uploads to my webserver I have tried various methods but there is always something not working...

Here is my latest code but having problems with the return being an Int and if I change the<br /> AsyncTask Int then it errors because the imagePath being passed to it is a String...

This is the error

Type mismatch: cannot convert from int to String

For return 0 and return serverResponseCode;

public class wardrobe extends Activity implements OnClickListener { // set variable for the fields private EditText nameField, sizeField, colorField, quantityField; private Spinner typeField, seasonField; private ImageView imageview; private ProgressBar progressBarField; private TextView imageTextSelect, resImage; private ProgressDialog progressDialog = null; private int serverResponseCode = 0; private Button uploadImageButton, postWardrobe; private String upLoadServerUri = null; private String imagepath = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.wardrobe); // image upload stuff imageview = (ImageView) findViewById(R.id.user_photo); imageTextSelect = (TextView) findViewById(R.id.imageTextSelect); // button for upload image uploadImageButton = (Button) findViewById(R.id.uploadImageButton); // button for posting details postWardrobe = (Button) findViewById(R.id.postButton); uploadImageButton.setOnClickListener(this); postWardrobe.setOnClickListener(this); @Override public void onClick(View v) { if (v == uploadImageButton) { // below allows you to open the phones gallery Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult( Intent.createChooser(intent, "Complete action using"), 1); } if (v == postWardrobe) { // validate input and that something was entered if (nameField.getText().toString().length() < 1 || colorField.getText().toString().length() < 1 || sizeField.getText().toString().length() < 1 || quantityField.getText().toString().length() < 1) { // missing required info (null was this but lets see) Toast.makeText(getApplicationContext(), "Please complete all sections!", Toast.LENGTH_LONG) .show(); } else { JSONObject dataWardrobe = new JSONObject(); try { dataWardrobe.put("type", typeField.getSelectedItem() .toString()); dataWardrobe.put("color", colorField.getText().toString()); dataWardrobe.put("season", seasonField.getSelectedItem() .toString()); dataWardrobe.put("size", sizeField.getText().toString()); dataWardrobe.put("quantity", quantityField.getText() .toString()); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } // make progress bar visible progressBarField.setVisibility(View.VISIBLE); // execute the post request new dataSend().execute(dataWardrobe); // image below progressDialog = ProgressDialog.show(wardrobe.this, "", "Uploading file...", true); imageTextSelect.setText("uploading started....."); new Thread(new Runnable() { public void run() { doFileUpload(imagepath); } }).start(); } } } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && requestCode == 1) { // Bitmap photo = (Bitmap) data.getData().getPath(); Uri selectedImageUri = data.getData(); imagepath = getPath(selectedImageUri); Bitmap bitmap = BitmapFactory.decodeFile(imagepath); imageview.setImageBitmap(bitmap); // add to text view what was added imageTextSelect.setText("Uploading file path: " + imagepath); } } public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); }

Here is the part I am struggling with:

public int doFileUpload(String sourceFileUri) { String upLoadServerUri = "http://10.0.2.2/wardrobe"; String fileName = imagepath; 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(imagepath); if (!sourceFile.isFile()) { progressDialog.dismiss(); Log.e("uploadFile", "Source File not exist :" + imagepath); runOnUiThread(new Runnable() { public void run() { imageTextSelect.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"; imageTextSelect.setText(msg); Toast.makeText(wardrobe.this, "File Upload Complete.", Toast.LENGTH_SHORT) .show(); } }); } // close the streams // fileInputStream.close(); dos.flush(); dos.close(); } catch (MalformedURLException ex) { progressDialog.dismiss(); ex.printStackTrace(); runOnUiThread(new Runnable() { public void run() { imageTextSelect .setText("MalformedURLException Exception : check script url."); Toast.makeText(wardrobe.this, "MalformedURLException", Toast.LENGTH_SHORT).show(); } }); Log.e("Upload file to server", "error: " + ex.getMessage(), ex); } catch (Exception e) { progressDialog.dismiss(); e.printStackTrace(); runOnUiThread(new Runnable() { public void run() { imageTextSelect.setText("Got Exception : see logcat "); Toast.makeText(wardrobe.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show(); } }); Log.e("Upload file to server Exception", "Exception : " + e.getMessage(), e); } progressDialog.dismiss(); return serverResponseCode; } // End else block }

Answer1:

I see many several problems here. First, you almost never (if ever) want to call runOnUiThread() from AsyncTask. Every method of AsyncTask runs on the UI except for doInBackground() so this usually isn't needed and often causes problems. Update the UI with the correct methods depending on what you are doing.

Second, I think you misunderstand what doInBackground() is returning. Its result is returned to onPostExecute() which is the 3rd param in your class declaration

private class doFileUpload extends AsyncTask <String, Void, String> {

So this means that onPostExecute() (which I don't see you overriding) should expect a String and that is what doInBackground() should return. So you should convert your return variables to String if you want to pass a String to onPostExecute()

<a href="http://developer.android.com/reference/android/os/AsyncTask.html" rel="nofollow">AsyncTask Docs</a>

Typically

progressDialog.dismiss();

is called in onPostExecute() and

progressDialog.show();

would be called in onPreExecute() when using an AsyncTask. Then you don't have to create a new Thread in your onClick().

Recommend

  • Unable to retrieve number before incoming call in marshmallow
  • IllegalStateException “System services not available to Activities before onCreate()”
  • android.app.PendingIntent cannot be accessed ouside the package
  • FCM Data messages are not working properly
  • How to get the url of a file of google drive to download in android
  • event.getSource() returns null Accessibility in android
  • Loading Bitmap to ImageView from URL in android
  • How to Make a Spinner (In a Fragment) That Changes the App's Language?
  • New Firebase failed: First argument must be a valid firebase URL and the path can't contain “.”
  • JSON encode and decode on PHP
  • Building Qt project for C++11 standard
  • For loop with if condition on multiple R functions
  • Convert Type Decimal to Hex (string) in .NET 3.5
  • Does Mobilefirst provide a provision to access web services directly?
  • Get history of file changes from TFS to implement custom “blame”-behaviour of exceptions
  • Abort upload large uploads after reading headers
  • How to rebase a series of branches?
  • java.lang.NoClassDefFoundError: com.parse.Parse$Configuration$Builder on below Lollipop versions
  • Volley JsonObjectRequest send headers in GET Request
  • Javascript convert timezone issue
  • Data Validation Drop Down Box Arrow Disappearing
  • retrieve vertices with no linked edge in arangodb
  • Codeigniter doesn't let me update entry, because some fields must be unique
  • Proper way to use connect-multiparty with express.js?
  • Trying to get generic when generic is not available
  • Why joiner is not used after Sequence generator or Update statergy
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • embed rChart in Markdown
  • Change div Background jquery
  • File not found error Google Drive API
  • How to get Windows thread pool to call class member function?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • apache spark aggregate function using min value
  • Is it possible to post an object from jquery to bottle.py?
  • Does armcc optimizes non-volatile variables with -O0?
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • UserPrincipal.Current returns apppool on IIS
  • java string with new operator and a literal