Get JSON from an HTTP Post to an Algolia server on Android - android

Not sure how to correctly put together the headers for a POST query to an Algolia server using Java in Android.
I have all the info about the request headers from recording the network info in Chrome's dev console
I have the query string parameters:
x-algolia-api-key
x-algolia-application-id
x-algolia-agent
and the form data params
query
hitsPerPage
facets
not working Android Code:
URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("accept", "application/json");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("query", queryString);
con.setRequestProperty("hitsPerPage", "20");
con.setRequestProperty("facets", "*");
con.setUseCaches(false);
con.setDoInput(true);
con.setDoOutput(true);
This keeps returning a 404 error but it's likely not set up right, really new to network connectivity on Android, anything helps!

I personally used the Algolia PHP API client (on github) in order to perform the search queries, which helps me to don't have to worry about the REST spec.
That one makes things easier to integrate to an Android app, but also integrates a retry mechanism that improves the connection reliability between the device and the API in case of network issue.
The same search query looks like that:
APIClient client = new APIClient("YourApplicationID", "YourAPIKey");
Index index = client.initIndex("YourIndexName");
index.searchASync(new Query(queryString), this)
.setFacets("*", this)
.setNbHitsPerPage(20), this);

You should never do a direct request to Algolia's servers, as you would lose all the logic and optimizations they put in place in their API Clients.
Using the Android API Client, doing a search query is simple:
Index index = new APIClient("YourApplicationID", "YourAPIKey")
.initIndex("YourIndexName");
JSONObject result = index.search(new Query(queryString)
.setFacets("*").setHitsPerPage(20));
But have a look at InstantSearch Android, Algolia's library to build search interfaces. It will be easier, faster, and safer to use it than the API Client.

Related

Spotify Android - Make Authorized Web Requests

I'm working on an Android app that implements the Spotify API to allow the users to listen to music. I've configured the Player that Spotify has created for android devices, but it's incredibly limited in terms of its functionality, so I've had to go through Spotify's Web API to do more advanced features.
I've hit a bug when trying to get a list of the user's own playlists. I'm making a request using:
URL url = new URL("https://api.spotify.com/v1/me/playlists");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
But instead of this command going through like it does for the other web API requests I've made, it throws the error:
java.io.FileNotFoundException: https://api.spotify.com/v1/me/playlists
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:242)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:25)
at com.tmacstudios.spotifyvoice.WebWrapper$override.searchUserPlaylist(WebWrapper.java:257)
at com.tmacstudios.spotifyvoice.WebWrapper$override.access$dispatch(WebWrapper.java)
at com.tmacstudios.spotifyvoice.WebWrapper.searchUserPlaylist(WebWrapper.java:0)
at com.tmacstudios.spotifyvoice.MainActivity$6.run(MainActivity.java:382)
at java.lang.Thread.run(Thread.java:818)
I'm not entirely sure why I'm getting this error, but I think it may have to do with not having the necessary authorization to make this request. Can anyone please help me solve this problem?
After studying the documentation some more, I was able to figure out a way to solve my problem. I was in fact getting the error since I wasn't using the proper authorization.
You can get the authorization token in OnActivityResult using this code:
AuthenticationResponse response = AuthenticationClient.getResponse(resultCode, intent);
if (response.getType() == AuthenticationResponse.Type.TOKEN) {
authToken = response.getAccessToken();
Log.e("MainActivity","Auth Token: "+authToken.toString());
...
Then when making the URL request, just pass in the authorization token as a header.
URL url = new URL("https://api.spotify.com/v1/me/playlists");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Authorization", "Bearer " + authToken);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
...
Also note that you must have the permissions you are using enabled as scopes when you are forming the authorization request initially.

Difference between okhttp and httpurlconnection?

What are the differences between these 2 libraries?
How I understood there is a difference between these 2 lib also because Volley uses httpurlconnection and Retrofit the okhttp....
But I don't understand the difference between them and pros and cons of both solutions. When is okhttp better and when httpurlconnection?
I would like to know so I know when should I use them.
EDIT:
Why does android use okhttp for the httpurlconnection? before httpurlconnection was not using okhttp if I am not wrong
Pros of okHttp
OkHttp can be customized for every request easily — like timeout customization, etc. for each request.
OkHttp perseveres when the network is troublesome: it will silently recover from common connection problems. If your service has multiple IP addresses OkHttp will attempt alternate addresses if the first connect fails.
Complete analytics of any request can be obtained. You can know bytes sent, bytes received, and the time taken on any request. These analytics are important so that you can find the data usage of your application and the time taken for each request, so you can identify slow requests.
Using OkHttp is easy. Its request/response API is designed with fluent builders and immutability. It supports both synchronous blocking calls and async calls with callbacks.
OkHttp supports Android 2.3 and above. For Java, the minimum requirement is 1.7.
HttpURLConnection
Advantages:
Lightweight APIs help in easier management and reduces compatibility issues.
Automatic handling of the caching mechanisms, with the help of
HttpResponseCache.
Reduces the network usage and also, the battery consumption.
Query Parameter:
URI baseUri = new URI("www.exemple.com/search");
URI uri = applyParameters(baseUri, "word","java");
HttpURLConnection connection =
(HttpURLConnection) uri.toURL().openConnection();
connection.setDoInput(true);
connection.setDoOutput(false);
connection.setRequestMethod("GET");
connection.connect();
if (connection.getResponseCode() ==
HttpURLConnection.HTTP_OK) {
// ...
}
Android Headers Example:
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("CustomHeader", token);
OkHttp
Advantages:
Connection pooling
Gziping
Caching
Recovering from network problems
Redirects
Retries
Support for synchronous and asynchronous calls
Query Parameter:
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://httpbin.org/get").newBuilder();
urlBuilder.addQueryParameter("website", "www.journaldev.com");
urlBuilder.addQueryParameter("tutorials", "android");
String url = urlBuilder.build().toString();
Request request = new Request.Builder()
.url(url)
.build();
Android Headers Example:
Request request = new Request.Builder()
.header("Authorization", "replace this text with your token")
.url("your api url")
.build();
The API's are different, personally I prefer the OkHttp ones.
Note that starting from Android 4.4, the networking layer (so also the HttpUrlConnection APIs) is implemented through OkHttp.

Sending POST request from android to RoR app, but cannot find the right URL

I am not able to reach the create Method in tests_controller.rb with this code.
String newUrl = "http://10.0.2.2:3000/tests";
httpcon = (HttpURLConnection) ((new URL(newUrl).openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
httpcon.connect();
And here is my routes.rb (I use model scaffold to create the RoR app).
resources :tests
Am i wrong in routing or something. When i run this code in Android, the create method is not run at all.
It's hard to tell the reason for the failure you have. Your routes seem OK. You can check couple other things:
Is your Rails server listening on the right interface and port?
Is there any network problem between the machine your client is working on and the server?
Instead of going through the cycle of edit-compile-deploy-run of Android, simply use curl or a similar tool to try the POST request from the console.
When you pinpoint the place of the problem, then you can ask another question, or, more likely, already find the answer online.

Android connect to Mysql database tutorial

Does anybody know a complete and working tutorial about how to retrieve data from MYSQL and display it in Android? I'm asking this because all the tutorials I found are older than API 22 and from API 22 the HttpClient is deprecated. And I'm a new Android Developer so I can't write any code on my own. :)
HttpClient
Interface for an HTTP client. HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features. Thread safety of HTTP clients depends on the implementation and configuration of the specific client.
This interface was deprecated in API level 22.
Please use openConnection() instead.
Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases.
For Gingerbread and better, HttpURLConnection is the best choice. Its simple API and small size makes it great fit for Android. Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.
Please visit this webpage for further details.
http://android-developers.blogspot.in/2011/09/androids-http-clients.html
An URLConnection for HTTP (RFC 2616) used to send and receive data over the web. Data may be of any type and length. This class may be used to send and receive streaming data whose length is not known in advance.
Uses of this class follow a pattern:
Obtain a new HttpURLConnection by calling URL.openConnection() and casting the result to HttpURLConnection.
Read the response. Response headers typically include metadata such as the response body's content type and length, modified dates and session cookies. The response body may be read from the stream returned by getInputStream(). If the response has no body, that method returns an empty stream.
For example, to retrieve the webpage at http://www.android.com/:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
finally {
urlConnection.disconnect();
}
}
Please visit this webpage for further details.
http://developer.android.com/reference/java/net/HttpURLConnection.html
urlconnection tutorials, can visit this websites
+http://www.vogella.com/tutorials/AndroidNetworking/article.html
+http://javatechig.com/android/android-networking-tutorial

Right way to manage HTTP connection in Android

I have written two programs which handle the HTTP request. I wanted to know if one is better than other -
Program 1 (Using HttpURLConnection)
URL url = new URL("https://www.google.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(false);
connection.connect();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
stringBuilder = new StringBuilder();
Program 2 (Using HttpPost)
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("https://test.com");
HttpResponse httpResponse = httpClient.execute(httpPost);
InputStream inputStream = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
Also in program 2, I use a singleton to get the connection object. But in program 1 there is no global connection object and I need to recreate the HttpURLConnection object everytime I make a request. Please let me know if I am on the right track.
Thank You
I would like to suggest you to use Android Asynchronous Http Client library.
Then you can avoid these basic stuffs. The one things I like most is HTTP requests happen outside the UI thread.
Also in program 2, I use a singleton to get the connection object. But in program 1 there is no global connection object and I need to recreate the HttpURLConnection object everytime I make a request.
Method 2 looks like simpler, but it's so old :
Apache HTTP Client - HTTPPost
DefaultHttpClient and its sibling AndroidHttpClient are extensible
HTTP clients suitable for web browsers. They have large and flexible
APIs. Their implementation is stable and they have few bugs. But the
large size of this API makes it difficult for us to improve it without
breaking compatibility. The Android team is not actively working on
Apache HTTP Client.
HttpURLConnection
HttpURLConnection is a general-purpose, lightweight HTTP client
suitable for most applications. This class has humble beginnings, but
its focused API has made it easy for us to improve steadily.
Prior to Froyo, HttpURLConnection had some frustrating bugs.
We should choose method 1 when :
For Gingerbread and better, HttpURLConnection is the best choice. Its
simple API and small size makes it great fit for Android. Transparent
compression and response caching reduce network use, improve speed and
save battery. New applications should use HttpURLConnection; it is
where we will be spending our energy going forward.
And method 2 when :
Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases.
Thanks,

Categories

Resources