Hello. This time, let's hit the Web API on Android. I will write it so that even those who hit the Web API for the first time can read it. There are various ways to hit the WebAPI, but use the Java standard library HttpURLConnection
. There are no complicated settings, and I think it is an orthodox method if it is used to hit the Web API.
If you hit WebAPI, you will receive JSON
as a return value, but since it is difficult to format JSON and output it to the screen on Android, we will implement Android while using the curl
command. I will. When using WebAPI, I think that it will be much easier to work with the curl command.
The development environment is as follows. *Android Studio 4.0.1 *targetSdkVersion 28 *Google Nexus 5x
curl command *Ubuntu 20.04 LTS (WSL 2)
If you want to make a music lyrics app or a translation app. It takes time and effort to collect data on the lyrics of music that increases in real time, and to collect the data to create a translation function. If it is difficult to make it yourself, I think you will use the library. What to do if you cannot find the standard library or external library even if you search for them. What to do if you want to handle data that changes in real time, such as lyrics, or if you want to use a library that does not depend on the programming language. You should look for the Web API.
WebAPI is not language-dependent and is often linked to a database, so it is good at handling real-time data and huge amounts of data. Internet connection is a prerequisite for using HTTP communication, but in the case of Android, it is natural that you can always connect to the Internet, so there is no problem even if you create an application using Web API. Note that you need to be careful when the Web API cannot be used temporarily due to maintenance or the specifications are changed.
If you explain it strictly, it will be difficult to understand, so if you explain roughly while making the meaning of each term a little vague, WebAPI refers to the part or interface of a Web service that is allowed to be accessed by the developer from the program. Accessing the WebAPI programmatically is called a request, and returning the result of the request is called a response. To send a request, you need to specify the URL and HTTP method. The HTTP method uses the most basic GET
and POST
. The specifics of how to send the request and what the response will be are as follows.
request
URL | HTTP method |
---|---|
http://example.com/api/get |
GET |
http://example.com/api/post |
POST |
response
{
"name": "foge"
}
In this way, when you make a request, the response will be returned in the form JSON
. The GET method is mainly used to get the data, and the POST method is mainly used when you want to include the data in the request and send it.
--The easiest way to test HTTP communication is to use httpbin HP. Normally, registration and API key acquisition are required to use WebAPI, but httpbin's HP does not require them. You can try HTTP communication without registration. This time we will use this. ――I won't explain it in this article, but if you want to try registration and API key acquisition, I think you should use OpenWeatherMap, which is easy to acquire API key. .. Getting the current weather in Tokyo is explained on various web pages, so you can easily try it.
Various tests can be performed by adding the specified parameters after the URL http://httpbin.org
. This time, we will use the following functions.
function | URL |
---|---|
Obtaining an IP address | http://httpbin.org/ip |
GET request test | http://httpbin.org/get |
Testing POST request | http://httpbin.org/post |
If you want to use the curl command on Windows, install WSL2
or install the curl command for Windows. WSL2 is the easiest way to use the Linux environment on Windows, so it's easy to set up. I will not touch on the installation method here.
The curl command can be used for a variety of purposes, but it is often used when making HTTP requests. Now, let's actually hit the Web API using httpbin
.
Use the GET method to get the IP address and test the GET request. The curl command makes a GET request if no options are added.
--Getting an IP address
request
curl http://httpbin.org/ip
response
{
"origin": "111.111.111.111" #IP address is different for each
}
--Testing GET request
request
curl http://httpbin.org/get
response
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.68.0",
"X-Amzn-Trace-Id": "Root=1-5f4f2fa5-80f8b602a2eec73861aa12e8"
},
"origin": "111.111.111.111",
"url": "http://httpbin.org/get"
}
--Testing POST request
To make a POST request, specify the HTTP method with the option -X
of the curl command. With -d
, you can describe the data to be included in the POST request. In httpbin, the data included in the request is set in the return value " form "
. When sending JSON, it is necessary to specify Content-Type
. Use the request header option -H
.
request
curl -X POST -H 'Content-Type: application/json' -d "name=foge&type=fogefoge" http://httpbin.org/post
response
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "foge"
"type": "fogefoge"
},
"headers": {
"Accept": "*/*",
"Content-Length": "9",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "curl/7.68.0",
"X-Amzn-Trace-Id": "Root=1-5f4f32d3-65c03ae0882434bae32b8070"
},
"json": null,
"origin": "111.111.111.111",
"url": "http://httpbin.org/post"
}
On Android, it is not possible to format and display the response result as easily as the curl command. I think it is better to hit the Web API on Android while checking whether the appropriate URL can be specified by using the curl command and whether the output is correct. This time, I would like to get the necessary information on Android while using the result of curl executed above.
First, in order to connect to the Internet, write the following in ʻAndroidManifest.xml`.
<uses-permission android:name="android.permission.INTERNET"/>
HttpURLConnection
You need to make some connection settings before starting communication. It is summarized in the table below.
Connection settings | Description |
---|---|
Connection timeout | Limitation on the time it may take to connect with the connect method. |
Read timeout | Time taken to acquire data (time required to make a request and return a response) |
User-Agent | Stores information such as software and OS that make requests(HereIseasytounderstand) |
Accept-Language | Indicates which language the client can understand and what kind of locale is recommended |
HTTP method | To tell the server what you want it to do |
Permission to send request body | Permission to store and send data in the request body |
Response body reception permission | Permission to receive data stored in the response body |
Now, let's show a program that actually performs HTTP communication using HttpURLConnection
. Since HttpURLConnection
cannot be executed in the UI thread, it is necessary to create another thread and execute it.
First, make a GET request to get the IP address.
public String getAPI(){
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
String result = "";
String str = "";
try {
URL url = new URL("http://httpbin.org/ip");
//Open a connection to the destination URL. Not connected yet
urlConnection = (HttpURLConnection) url.openConnection();
//Set connection timeout
urlConnection.setConnectTimeout(10000);
//Set response data read timeout
urlConnection.setReadTimeout(10000);
//User in header-Set Agent
urlConnection.addRequestProperty("User-Agent", "Android");
//Accept in header-Set Language
urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
//Specify HTTP method
urlConnection.setRequestMethod("GET");
//Do not allow submission of request body
urlConnection.setDoOutput(false);
//Allow reception of response body
urlConnection.setDoInput(true);
//Start communication
urlConnection.connect();
//Get response code
int statusCode = urlConnection.getResponseCode();
//Response code 200 indicates that communication was successful.
if (statusCode == 200){
inputStream = urlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
//Get the response result line by line and add it to str
result = bufferedReader.readLine();
while (result != null){
str += result;
result = bufferedReader.readLine();
}
bufferedReader.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Return JSON of response result as String type
return str;
}
Next, make a POST request.
public String postAPI(){
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
String str = "";
try {
URL url = new URL("http://httpbin.org/post");
//Open a connection to the destination URL. Not connected yet
urlConnection = (HttpURLConnection) url.openConnection();
//Data to be stored in the request body
String postData = "name=foge&type=fogefoge";
//Set connection timeout
urlConnection.setConnectTimeout(10000);
//Set response data read timeout
urlConnection.setReadTimeout(10000);
//User in header-Set Agent
urlConnection.addRequestProperty("User-Agent", "Android");
//Accept in header-Set Language
urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
//Specify HTTP method
urlConnection.setRequestMethod("POST");
//Allow reception of response body
urlConnection.setDoInput(true);
//Allow submission of request body
urlConnection.setDoOutput(true);
//Start communication
urlConnection.connect();
//Write the request body
outputStream = urlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
bufferedWriter.write(postData);
bufferedWriter.flush();
bufferedWriter.close();
//Get response code
int statusCode = urlConnection.getResponseCode();
//Response code 200 indicates that communication was successful.
if (statusCode == 200){
inputStream = urlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//Get the response result line by line and add it to str
result = bufferedReader.readLine();
while (result != null){
str += result;
result = bufferedReader.readLine();
}
bufferedReader.close();
}
urlConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Return JSON of response result as String type
return str;
}
As a result of the HTTP communication mentioned above, JSON can be acquired as a character string. Create a JSON object from the character string and extract the contents.
** Extract the IP address from the return value of the GET request **
//Get the return value of the GET request function. See the implementation of the GET request above.
response = getAPI();
//Create a JSON object from a character string and use this as the root.
JSONObject rootJSON = new JSONObject(response);
//http with curl://httpbin.org/Refer to the output result when requesting to ip
//Just below the route"origin"Get the value (character string) of the key
ip = rootJSON.getString("origin");
** Extract the value set in the request body from the return value of POST request **
From the output result of making a POST request with the curl command, you can confirm that the value set in the request body is stored in " form "
. Extract the value of the request body stored in " form "
.
//Get the return value of the POST request function. See the POST request implementation above.
response = getPOST();
//Create a JSON object from a character string and use this as the root.
JSONObject rootJSON = new JSONObject(response);
//Just below the route"form"Get JSONObject
JSONObject formJSON = rootJSON.getJSONObject("form");
// "form"Directly under JSONObject"name"with key"type"Get the key value (string)
nameAndType = formJSON.getString("name") + "/" + formJSON.getString("type");
Based on the above, the sample code is shown.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.samplehttpconnection">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
package com.example.samplehttpconnection;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private Handler handler = new Handler();
private Button button;
private Button button2;
private TextView textView;
private TextView textView2;
private String urlIpText = "http://httpbin.org/ip";
private String urlPostText = "http://httpbin.org/post";
private String ip = "";
private String nameAndType = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
button2 = findViewById(R.id.button2);
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
String response = "";
try {
response = getAPI();
JSONObject rootJSON = new JSONObject(response);
ip = rootJSON.getString("origin");
} catch (JSONException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
textView.setText(ip);
}
});
}
});
thread.start();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
String response = "";
try {
response = postAPI();
JSONObject rootJSON = new JSONObject(response);
JSONObject formJSON = rootJSON.getJSONObject("form");
nameAndType = formJSON.getString("name") + "/" + formJSON.getString("type");
} catch (JSONException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
textView2.setText(nameAndType);
}
});
}
});
thread.start();
}
});
}
public String getAPI(){
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
String result = "";
String str = "";
try {
URL url = new URL(urlIpText);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
urlConnection.addRequestProperty("User-Agent", "Android");
urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(false);
urlConnection.connect();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200){
inputStream = urlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
result = bufferedReader.readLine();
while (result != null){
str += result;
result = bufferedReader.readLine();
}
bufferedReader.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public String postAPI(){
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
String str = "";
try {
URL url = new URL(urlPostText);
urlConnection = (HttpURLConnection) url.openConnection();
String postData = "name=foge&type=fogefoge";
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
urlConnection.addRequestProperty("User-Agent", "Android");
urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.connect();
outputStream = urlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
bufferedWriter.write(postData);
bufferedWriter.flush();
bufferedWriter.close();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200){
inputStream = urlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
result = bufferedReader.readLine();
while (result != null){
str += result;
result = bufferedReader.readLine();
}
bufferedReader.close();
}
urlConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="GET"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="Hello World!"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="POST"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>