mardi 31 mars 2015

Upload Picture in Android to Server

I've been on this subject for weeks and I can't seem to find the answer I'm looking for. I've just started out learning this and I was hoping I could find some great resources to aid in my study. I've found some amazing references at GitHub, but only to find that I'm encountering problems every time I try and debug my app.


What I'm trying to achieve:



  1. To set up a picture upload page (for user's profile picture);

  2. Link the page to the server to store the uploaded pictures; And also try to implement this code by AB1209 to get a fix from loading from Photos app (instead of Gallery) on higher API androids;

  3. Find out a way to link the file path to the user's info at database. I.e. The User's profile picture. (I don't want to store it in BLOB)


I'm currently trying this code from GitHub: webile-android and so far it's very easy for me to understand what's on the code. However when I tried debugging the app (clicked on the image to upload), my app has stopped working at that point and I got the following error.


Any help would truly be appreciated!



04-01 10:06:35.801 1632-1632/worka.biz.worka E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: worka.biz.worka, PID: 1632
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:4007)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/entity/ContentType;
at org.apache.http.entity.mime.content.ByteArrayBody.<init>(ByteArrayBody.java:67)
at org.apache.http.entity.mime.content.ByteArrayBody.<init>(ByteArrayBody.java:87)
at worka.biz.worka.ManagePictureActivity.executeMultipartPost(ManagePictureActivity.java:111)
at worka.biz.worka.ManagePictureActivity.uploadPhoto(ManagePictureActivity.java:85)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.http.entity.ContentType" on path: DexPathList[[zip file "/data/app/worka.biz.worka-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.apache.http.entity.mime.content.ByteArrayBody.<init>(ByteArrayBody.java:67)
at org.apache.http.entity.mime.content.ByteArrayBody.<init>(ByteArrayBody.java:87)
at worka.biz.worka.ManagePictureActivity.executeMultipartPost(ManagePictureActivity.java:111)
at worka.biz.worka.ManagePictureActivity.uploadPhoto(ManagePictureActivity.java:85)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Suppressed: java.lang.ClassNotFoundException: org.apache.http.entity.ContentType
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 18 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available


This is the JAVA code handling the uploading function:



public class ManagePictureActivity extends Activity {

private static final String TAG = ManagePictureActivity.class.getSimpleName();

private static final int SELECT_PICTURE = 100;

private ImageView previewImage;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_picture);

previewImage = (ImageView) findViewById(R.id.previewImage);
}

public void pickPhoto(View view) {
//TODO: launch the photo picker
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK) {
Bitmap bitmap = getPath(data.getData());
previewImage.setImageBitmap(bitmap);
}
}

private Bitmap 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();
String filePath = cursor.getString(column_index);
cursor.close();
// Convert file path into bitmap image using below line.
Bitmap bitmap = BitmapFactory.decodeFile(filePath);

return bitmap;
}

public void uploadPhoto(View view) {
try {
executeMultipartPost();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void executeMultipartPost() throws Exception {

try {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

BitmapDrawable drawable = (BitmapDrawable) previewImage.getDrawable();

Bitmap bitmap = drawable.getBitmap();

bitmap.compress(CompressFormat.JPEG, 50, bos);

byte[] data = bos.toByteArray();

HttpClient httpClient = new DefaultHttpClient();

HttpPost postRequest = new HttpPost(AppConfig.FILE_UPLOAD_URL);

String fileName = String.format("File_%d.png",new Date().getTime());
ByteArrayBody bab = new ByteArrayBody(data, fileName);

// File file= new File("/mnt/sdcard/forest.png");

// FileBody bin = new FileBody(file);

MultipartEntity reqEntity = new MultipartEntity(

HttpMultipartMode.BROWSER_COMPATIBLE);

reqEntity.addPart("file", bab);

postRequest.setEntity(reqEntity);
int timeoutConnection = 60000;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 60000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpConnectionParams.setTcpNoDelay(httpParameters, true);

HttpResponse response = httpClient.execute(postRequest);

BufferedReader reader = new BufferedReader(new InputStreamReader(

response.getEntity().getContent(), "UTF-8"));

String sResponse;

StringBuilder s = new StringBuilder();

while ((sResponse = reader.readLine()) != null) {

s = s.append(sResponse);

}

System.out.println("Response: " + s);

} catch (Exception e) {

// handle exception here
e.printStackTrace();

// Log.e(e.getClass().getName(), e.getMessage());

}

}}


And also the XML code:



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://ift.tt/nIICcg"
xmlns:tools="http://ift.tt/LrGmb4"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="false"
android:orientation="vertical" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical" >

<ImageView
android:id="@+id/previewImage"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="0.5" />

<Button
android:onClick="pickPhoto"
android:layout_height="@dimen/login_height"
android:layout_width="@dimen/login_width"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:background="#80f1ce25"
android:textAllCaps="false"
android:textColor="#ffffff"
android:textSize="25sp"
android:textStyle="normal"
android:text="Select from gallery"/>

<Button
android:onClick="uploadPhoto"
android:layout_height="@dimen/login_height"
android:layout_width="@dimen/login_width"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:background="#80f1ce25"
android:textAllCaps="false"
android:textColor="#ffffff"
android:textSize="25sp"
android:textStyle="normal"
android:text="Upload photo to server"/>

</LinearLayout>

</RelativeLayout>


And my php file (directed from AppConfig.FILE_UPLOAD_URL) is as follows: This php file is from AndroidHive because the previous reference seems to have omitted this detail. So I thought this might work.



fileUpload.php
<?php

// Path to move uploaded files
$target_path = "uploads/";

// array for final json respone
$response = array();

// getting server ip address
$server_ip = gethostbyname(gethostname());

// final file url that is being uploaded
$file_upload_url = 'http://' . $server_ip . '/' . 'picture_upload_directory' . '/' . $target_path;

if (isset($_FILES['image']['name'])) {

$target_path = $target_path . basename($_FILES['image']['name']);

// reading other post parameters
$email = isset($_POST['email']) ? $_POST['email'] : '';
$website = isset($_POST['website']) ? $_POST['website'] : '';

$response['file_name'] = basename($_FILES['image']['name']);
$response['email'] = $email;
$response['website'] = $website;

try {
// Throws exception incase file is not being moved
if (!move_uploaded_file($_FILES['image']['tmp_name'], $target_path)) {
// make error flag true
$response['error'] = true;
$response['message'] = 'Could not move the file!';
}

// File successfully uploaded
$response['message'] = 'File uploaded successfully!';
$response['error'] = false;
$response['file_path'] = $file_upload_url . basename($_FILES['image']

['name']);
} catch (Exception $e) {
// Exception occurred. Make error flag true
$response['error'] = true;
$response['message'] = $e->getMessage();
}
} else {
// File parameter is missing
$response['error'] = true;
$response['message'] = 'Not received any file!';
}



// Echo final json response to client
echo json_encode($response);
?>

Aucun commentaire:

Enregistrer un commentaire