I'm using OkHttp to upload files to Google Cloud Storage. Right now, I'm doing a single PUT request with a custom request body and stream the data. The request is something like this:
final Request request = new Request.Builder()
.url(uploadUrl)
.put(requestBody)
.addHeader("Content-Length", length)
.addHeader("Content-Range", range)
.build();
My requestBody handles reading of the file and writing to the BufferedSink, similar to the recipe for Post Streaming available here (https://github.com/square/okhttp/wiki/Recipes):
Will it be faster to move to uploading Multiple Chunks (as described here: https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload#upload-resumable - I think it should be achievable with OkHttp MultipartBody.Builder), or should I stick with streaming?
Related
So I want to build an android application, that users can take videos on, then send them to a web server to perform analysis on the video, send back metrics in JSON and also send back several images from the video. Is this possible? Is it a good/bad idea? If this is a dumb approach or this will be a very slow approach, any better strategies are welcome. Cheers!
Yes you can send video file to web-server and get response via JSON with images.
For sending video you can HTTP client retrofit which is very handy. You must use #Multipart in your API calling. Here is an example.
#POST("/your_url/")
Call<ResultObject> uploadVideoToServer(#Part MultipartBody.Part video);
You can call it like:
File videoFile = new File(pathToVideoFile);
RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);
Your need a dedicated server (aws or digital ocean droplet) and well formed web apps in server (algorithm) to extract picture from your video for better user experience. Overall your idea is good & it's possible.
Is it mandatory that I write every single query into .graphql files to be used afterwards in the code? Or can I just simply put the queries somehow in the code itself without any .graphql files?
I've searched a lot and the examples always have the .graphql files, but in a more complex app with a lot of queries it would be nicer to have them in the code rather than in graphql files.
If you are using Apollo client for android to consume graphql queries and mutation you have to put your queries and mutation in a .graphql files so apollo can build and generate classes for you to consume them.
Here is how to apollo client will generate classes for you
Also for how to consume the generated classes by apollo client here
I don't recommend to make queries in code because it's a lot of code that no readable and understandable.
Here is how to write queries in code
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/graphql");
RequestBody body = RequestBody.create(mediaType, "{\"query\":\"query weather($lat: Float, $lng: Float){\\n weather(lat: $lat, lng: $lng){\\n currentTemp\\n minTemp\\n maxTemp\\n icon\\n }\\n}\",\"variables\":{\"lat\":30.024663,\"lng\":31.485652},\"operationName\":\"weather\"}");
Request request = new Request.Builder()
.url(BASE_URL)
.post(body)
.build();
Response response = client.newCall(request).execute();
This is really unreadable and understable code generated by insomnia
We work on a project with Android frontend and django-rest-framework backend.
The Media files were served through Django Media files and we can cache media files and see them in the app when it was offline.
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'auth/login/', 'rest_framework_jwt.views.obtain_jwt_token',name='jwt_login'), # post username & password to get token
...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The problem was that we need to apply authorization on media files so I've removed media paths from urls and add a view to do the job
#api_view(['GET'])
def media_image_handler(request,url):
# extra code before serving media
...
...
# read and return media file to response
And the url.py changed to this:
urlpatterns = patterns('',
url(r'^media/(?P<url>.*)/$',media_image_handler, name='media'),
url(r'^admin/', include(admin.site.urls)),
url(r'auth/login/', 'rest_framework_jwt.views.obtain_jwt_token',name='jwt_login'),
)
Now we got 2 problems:
Due to extra code response time become higher
Cache files cannot be loaded offline
Now the question:
Is there any suitable method that can be used instead?
For example instead of full authentication use a random generated file names that cannot be guessed easily or whatever?
We will appreciate for any helpful opinion
P.S. We are using Retrofit and Picasso on Android
For first: static files should be served by servers like nginx or lighttpd. About your question. I think you are talking about controlled downloads. This feature calls X-Sendfile and implemented in nginx and other servers. You can read about it in Nginx documentation.
https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
According to the android documentations, I should be using AndroidHttp.HttpTransport instead of Apache as Apache may not be supported in the future, etc. etc. Does anyone know how to use AndroidHttp for sending multipart data to server? I need to upload a video to server along with title, username, timestamp, etc. Thanks for any help.
With apache, the following code works well for uploading multipart video: Android upload video to remote server using HTTP multipart form data
I'm trying to upload a jpeg image to my web server via an HTTP PUT method.
With Fiddler, I'm able to compose an HTTP PUT request, upload the image and execute the request successfully.
However, on Android, I can't get it to work. I've read many solutions about using MultipartEntity. When I try that, the image received on the server is corrupted. I compared the content of the original image with the one received by the server and I see that some HTTP headers are added at the beginning of the file and that the multipart boundary is added at the end, therefore corrupting it.
I've set up Fiddler on the web server as a reverse proxy to capture the incoming HTTP traffic:
here's the result
On the top, the HTTP PUT request sent with Fiddler that works.
At the bottom, the one sent by my Android application that sends a corrupted image.
How can I send an HTTP PUT request on Android that will produce a similar request than the one sent with Fiddler?