Friday, April 26, 2013

Uploading Image to Server Path Using MultipartEntity Library

Here the fallowing will explains how to upload the image to server.
using multipartentity using     httpmime-4.1.2.jar


The following code will help to acheives without loosing the Image quality




public class ImageUpload extends Activity {
private static final int PICK_IMAGE = 1;
private ImageView imgView;
private Button upload;
private EditText caption;
private Bitmap bitmap;
private ProgressDialog dialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imageupload);

imgView = (ImageView) findViewById(R.id.ImageView);
upload = (Button) findViewById(R.id.Upload);
caption = (EditText) findViewById(R.id.Caption);
upload.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {
if (bitmap == null) {
Toast.makeText(getApplicationContext(),
"Please select image", Toast.LENGTH_SHORT).show();
} else {
dialog = ProgressDialog.show(ImageUpload.this, "Uploading",
"Please wait...", true);
new ImageUploadTask().execute();
}
}
});

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.imageupload_menu, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.ic_menu_gallery:
try {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
PICK_IMAGE);
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
e.getMessage(),
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_IMAGE:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImageUri = data.getData();
String filePath = null;

try {
// OI FILE Manager
String filemanagerstring = selectedImageUri.getPath();

// MEDIA GALLERY
String selectedImagePath = getPath(selectedImageUri);

if (selectedImagePath != null) {
filePath = selectedImagePath;
} else if (filemanagerstring != null) {
filePath = filemanagerstring;
} else {
Toast.makeText(getApplicationContext(), "Unknown path",
Toast.LENGTH_LONG).show();
Log.e("Bitmap", "Unknown path");
}

if (filePath != null) {
decodeFile(filePath);
} else {
bitmap = null;
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Internal error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
}
break;
default:
}
}

class ImageUploadTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... unsued) {
try {

Date now = new Date(); // java.util.Date, NOT java.sql.Date or java.sql.Timestamp!
String format = new SimpleDateFormat("yyyyMMddHHmmss").format(now);
String fileName =format+".jpg";
String pID = "1000";
Log.i("Timestamp",fileName);
String url = "http://test.uspdhub.com/muspdhub1.0/m_service/Handler.ashx?PhotoCaption="+fileName+"&PID="+pID;

HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);

MultipartEntity entity = new MultipartEntity();

ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, bos);
byte[] data = bos.toByteArray();
Log.i("Bytes are",""+data.toString());
// entity.addPart("returnformat", new StringBody("json"));
entity.addPart("uploaded", new ByteArrayBody(data,"image/jpeg","image.jpg"));
// entity.addPart("photoCaption", new StringBody(caption.getText().toString()));
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost,
localContext);
String sResponse = EntityUtils.getContentCharSet(response.getEntity());
/*BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));

String sResponse = reader.readLine();*/
return sResponse;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}

// (null);
}

@Override
protected void onProgressUpdate(Void... unsued) {

}

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

if (sResponse != null) {

Toast.makeText(getApplicationContext(),
sResponse+" Photo uploaded successfully",
Toast.LENGTH_SHORT).show();
/*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(),
"Photo uploaded successfully",
Toast.LENGTH_SHORT).show();
caption.setText("");
}*/
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
e.getMessage(),
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
}
}

public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
// HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
// THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else
return null;
}

public void decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);

// The new size we want to scale to
final int REQUIRED_SIZE = 1024;

// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}

// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeFile(filePath, o2);

imgView.setImageBitmap(bitmap);

}
}



Tuesday, April 2, 2013

Handling OutOfMemory Exception When Sending or Uploading Large Images to the Server From Android Activity

This Post provides the solution for OutOfMemoryException for large image uploades or server requests as Base64 encoded String format.

The code as follows.

1) The image which I am picking from either camera or from gallery .

 Dialog for pick the image.


private void startDialog() {

AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(this);
myAlertDialog.setTitle("Upload Pictures Option");
myAlertDialog.setMessage("How do you want to set your picture?");

myAlertDialog.setPositiveButton("Gallery",
new DialogInterface.OnClickListener() {

public void onClick(DialogInterface arg0, int arg1) {
pictureActionIntent = new Intent(
Intent.ACTION_GET_CONTENT, null);
pictureActionIntent.setType("image/*");
pictureActionIntent.putExtra("return-data", true);
// Intent intent = new Intent(Intent.ACTION_PICK,
// android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(
pictureActionIntent, "Select Picture"),
GALLERY_PICTURE);
}
});

myAlertDialog.setNegativeButton("Camera",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {

pictureActionIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File f = null;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
pictureActionIntent.putExtra(
MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));

} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
startActivityForResult(pictureActionIntent,
CAMERA_PICTURE);
}
});
myAlertDialog.show();
}



2)  Next I will set the image to image view in OnActivityresult() method as follows.



public void onActivityResult(int requestCode, int resultCode, Intent data) {

if (resultCode == RESULT_OK) {

switch (requestCode) {

case GALLERY_PICTURE:

Log.i(TAG, "INSIDE GALLERY PICTURE>>>>>>>>>>>>>>>>>>>>");
if (data != null) {

Uri imageUri = data.getData();

if(bitmap != null && !bitmap.isRecycled()){
attachImage.setImageBitmap(bitmap);
bitmap.isRecycled();
bitmap = null;
}
try {
bitmap = MediaStore.Images.Media.getBitmap(
this.getContentResolver(), imageUri);
attachImage.setImageBitmap(bitmap);
attachImage.setVisibility(View.VISIBLE);
// getImageByteAsString(bitmap);

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

break;

case CAMERA_PICTURE:
Log.i(TAG, "INSIDE CAMERAPICTURE>>>>>>>>>>>>>>>>>>>>");
if (mCurrentPhotoPath != null) {
setPic();
// galleryAddPic();

} else {
if (data != null) {
Uri imageUri = data.getData();
if(bitmap != null && !bitmap.isRecycled()){
attachImage.setImageBitmap(null);
bitmap.recycle();
bitmap = null;
}
try {
bitmap = MediaStore.Images.Media.getBitmap(
this.getContentResolver(), imageUri);
attachImage.setImageBitmap(bitmap);
attachImage.setVisibility(View.VISIBLE);
// getImageByteAsString(bMap);

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
break;
}
}
}

3) I will decode the bitmap as follows.


private void setPic() {

/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */

/* Get the size of the ImageView */
int targetW = 200;
int targetH = 200;

/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;

/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW / targetW, photoH / targetH);
}

/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;

if (bitmap != null && !bitmap.isRecycled()) {
attachImage.setImageBitmap(null);
bitmap.recycle();
bitmap = null;
}

/* Decode the JPEG file into a Bitmap */
bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);

/* Associate the Bitmap to the ImageView */
attachImage.setImageBitmap(bitmap);
attachImage.setVisibility(View.VISIBLE);

// getImageByteAsString(bitmap);
}


4) Scaling the Image to overcome the out of memory exception while converting Base64 encoding format.


call the below method as requst of your image bytes in the form of Base64 encoded string.


private String getImageByteAsString(Bitmap bitmap) {
String bitmapStr = null;
try {

Bitmap bmap = Bitmap.createScaledBitmap(bitmap, 100, 100, true);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();

// here chance to get Out Of Memory Exception
bitmapStr = Base64.encodeToString(b, Base64.DEFAULT);

baos.close();
baos = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return bitmapStr;
}


the above scaled and recycled bitmap will solves the issue.