ericaddison / APT_miniProject_Android

The Android App for Connexus
0 stars 0 forks source link

Status of upload activity. #15

Open mspagon opened 6 years ago

mspagon commented 6 years ago

Regarding, #14

Stream can be started with:

putExtras("streamID", Long value)

as I am using the following to fetch the value:

streamID = getIntent().getExtras().getLong("streamID");

I tried to use what we have on our Python back-end server to upload a picture but I think what we have needs some modification. I need help with this since I don't 100% understand how the Python/HTML version works.

I think we might need: /service/requestUploadURL /service/androidUpload

I will elaborate on why during today's 8:30 PM meeting. But basically the the current blob upload URL "upload_url" is embedded in HTML and not passed as a JSON in a service. And the UPLOAD service handles the POST data as an HTML form and not as a JSON (need confirmation).

ericaddison commented 6 years ago

Yeah, the webz make me think you're on the right track, like the steps might be:

Is that what you think you'll have to do?

ericaddison commented 6 years ago

Also, could you write your upload activity to handle a possible incoming file name and location from the camera (and just ignore if those params are not there)? Something like if I launched from the camera activity and did

i.putExtra("image_filename",filename);
i.putExtra("image_lat", lat);
i.putExtra("image_lng", lng);

It seems like the EXIF location information might not be available immediately to grab from a brand new image file, so I thought I would just send it in explicitly...

ericaddison commented 6 years ago

mmm, alternatively, it might be possible to simplify the upload process a little bit by having android send the all the data (file (bytes), stream ID, lat/long) to the server once, then the server generates its own upload url (no need to send it back to android) and POSTs to that address itself (maybe? I seem to remember being confused about how to send a POST request from Python, but it might be easy if all you have to do is forward the request instead of rebuilding it). Then our server takes over again as normal.

This link might be helpful for how to pack binary data into a POST request from Android. https://stackoverflow.com/questions/7632737/android-send-a-image-and-save-url/7632849#7632849

mspagon commented 6 years ago

I have implemented the /service/getuploadurl and android has the unique url. I have also implemented converting the image to byte[] form.

image

However I still can't figure out HTTP Multipart POST:

The Appache HTTP API is old, people pointed me to OKHTTP3. It was simple and great! But i couldn't even get the most basic request to work (3-5 lines of code). Couldn't figure it out.

Also couldn't understand Volley's multipart post.

I'm going to turn in for the night.

Feel free to give it a shot in a test activity or add to Line 153 in upload_activity.

I put a //TODO

image

Michael

mspagon commented 6 years ago

Going to give it one more shot tonight. I did some digging around and found this great resource

http://loopj.com/android-async-http/

mspagon commented 6 years ago

looks like I don't even need to convert it to a byte[] which makes it more straightforward

mspagon commented 6 years ago

Here's what I did. I'm very close. But I think I'm out of time. Any help appreciated.

I added an upload helper class. so you can make simple calls:

UploadHelper.postImage(String uploadUrl, Uri picturePath, String streamID, double lat, double lng);

Looking at our HTTP form:

image

I created an HTTP Post in Android that matches:

    public static void postImage(String uploadUrl, Uri picturePath, String streamID, double lat, double lng) {
        // http://loopj.com/android-async-http/
        // search for "Uploading Files with RequestParams"
        File imgFile = new File(picturePath.getPath());
        RequestParams params = new RequestParams();
        try {
            params.put("file", imgFile);
            params.put("streamID", streamID);
            params.put("lat", lat);
            params.put("lng", lng);
            params.put("redirect", "https://apt17-miniproj-whiteteam.appspot.com/");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // http://loopj.com/android-async-http/doc/com/loopj/android/http/AsyncHttpClient.html
        AsyncHttpClient client = new AsyncHttpClient();
        Log.d("postImage", "file name: " + imgFile.getPath());
        Log.d("postImage", uploadUrl);
        Log.d("postImage", "ID, lat, lng " + streamID + ", " + Double.toString(lat) + ", " + Double.toString(lng));
        client.post(uploadUrl, params, new AsyncHttpResponseHandler() {}
........
}

My log output failure is this, it uploads the image but fails on a second request of some type? maybe the actual back end server handling it after the blobstore:

image

I even see ... part? of the file uplaoded on the google cloud platform console... but the filetype is different sizes each time making me think it didn't complete.

image

Also noticed that the file path is different from the file chooser vs. the camera. And it seems to work better with the camer picture path.

mspagon commented 6 years ago

tl;dr - something makes me suspect that the form data doesn't match and the back end server doesn't handle it correctly after the upload finishes.

ericaddison commented 6 years ago

Hmm... don't send in the redirect parm for one thing .. that's for the Web client. I will look at this http library you used, but I'm surprised if you didn't have to specify "multipart" anywhere, and that you can really get away with just giving it a File object.