In Previous article, I explained how to use HttpURLConnection using httpbin as a Web API. This time, we will use Flask as a Web API and perform HTTP communication (GET / POST) between Android and Flask. For a detailed explanation of the HttpURLConnection and curl commands, refer to Previous article.
*Android Studio 4.0.1 *targetSdkVersion 28 *Google Nexus 5x
curl command, python *Ubuntu 20.04 LTS (WSL 2) *Python 3.7.3
HTTP communication using the GET method can be easily realized. For Android side, please refer to Previous article. The code on the Android side is also written in the sample code shown at the end. Here, we will describe the Flask side.
app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/get', methods=['GET'])
def get():
#Create a response to a GET request
response = {'result': 'success', 'status': 200}
#Return as JSON object
return jsonify(response)
Let's send a request using the curl command.
curl http://127.0.0.1:5000/api/get
You should see a response like the one below.
{
"result": "success",
"status": 200
}
This section describes HTTP communication using the POST method.
There are three ways to read JSON format data. This time, we will read the data received by the POST request.
app.py
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route('/api/post', methods=['POST'])
def post():
#Method 1
#Request the data received by POST.If you retrieve the data, you can see that it is a bytes type.
print(type(request.data))
#Even if you output it, you can see that it is a bytes type
print(request.data)
#Since it is a bytes type, decode it to convert it to a character string
print(request.data.decode('utf-8'))
#A string written in JSON format can be converted to a dictionary type by the loads method.
data = json.loads(request.data.decode('utf-8'))
print(data)
#Method 2
#In the loads method, bytes type and bytearray type can be entered in addition to the character string.
data = json.loads(request.data)
print(data)
#Method 3
# request.By using the json method, the data received by POST can be treated as a dictionary type.
#This is the fastest way to write, so I recommend it.
print(request.json)
#Adopt method 3 and return JSON object as return value
data = request.json
return jsonify(data)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Execute app.py and try sending a POST request using curl. Open a new terminal and execute the following command. The body describes a character string in JSON format.
curl -X POST -H 'Content-Type:application/json' -d `{"name": "foge", "value": "fogefoge"}` http://127.0.0.1:5000/api/post
When the curl command is executed, the following is output to the terminal where app.py is executed. It can be confirmed that the output of the bottom three lines is the same.
<class 'bytes'>
b'{"name": "foge", "value": "fogefoge"}'
{"name": "foge", "value": "fogefoge"}
{'name': 'foge', 'value': 'fogefoge'}
{'name': 'foge', 'value': 'fogefoge'}
{'name': 'foge', 'value': 'fogefoge'}
In order to read the data of the character string written in JSON format sent from Android in Python, it is necessary to describe the body according to the JSON format on Android. Specifically, do as follows.
String postData = "{\"name\": \"foge\", \"value\": \"fogefoge\"}";
In this way, since it is necessary to describe double quotation marks in the character string, it is described using an escape sequence. If you want to embed variable data in a character string, write as follows.
String name = "foge";
int value = 100;
String postData = String.format("{\"name\": \"%s\", \"value\": %d}", name, value);
However, since it is very troublesome to describe in this way, it is generally described as follows.
//Create an associative array
HashMap<String, Object> jsonMap = new HashMap<>();
jsonMap.put("name", "foge");
jsonMap.put("value", 100);
//Convert associative array to JSONObject
JSONObject responseJsonObject = new JSONObject(jsonMap);
//Convert JSONObject to a string
String postData = responseJsonObject.toString();
Then, the sample code is shown below.
app.py
from flask import Flask, request, jsonify
app = Flask(__name__)
#If the result of jsonify contains Japanese, you can avoid garbled characters by writing the following one line.
app.config['JSON_AS_ASCII'] = False
@app.route('/api/get', methods=['GET'])
def get():
response = {"result": "success", "status": 200}
return jsonify(response)
@app.route('/api/post', methods=['POST'])
def post():
data = request.json
name = data['name']
value = data['value']
array = data['array']
print(f'data: {data}')
print(f'data["name"]: {name}')
print(f'data["value"]: {value}')
print(f'data["array"]: {array}')
print(f'data["array[0]"]: {array[0]}')
print(f'data["array[1]"]: {array[1]}')
print(f'data["array[2]"]: {array[2]}')
return jsonify(data)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Before writing the Android sample code, please check if HTTP communication is possible once with curl.
curl http://127.0.0.1:5000/api/get
curl -X POST -H 'Content-Type:application/json' -d '{"name": "foge", "value": 100, "array":["Good morning", "Hello", "Good evening"]}' http://127.0.0.1:5000/api/post
The Android sample code is shown below.
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>
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:gravity="center"
android:text=""
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:gravity="center"
android:text=""
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>
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.ArrayList;
import java.util.HashMap;
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;
//Please change your IP address. Describe the IP address of the PC running the Python program
private String urlGetText = "http://192.168.0.10:5000/api/get";
private String urlPostText = "http://192.168.0.10:5000/api/post";
private String getResultText = "";
private String postResultText = "";
@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);
getResultText = rootJSON.toString();
} catch (JSONException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
textView.setText(getResultText);
}
});
}
});
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);
postResultText = rootJSON.toString();
} catch (JSONException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
textView2.setText(postResultText);
}
});
}
});
thread.start();
}
});
}
public String getAPI(){
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
String result = "";
String str = "";
try {
URL url = new URL(urlGetText);
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();
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
urlConnection.addRequestProperty("User-Agent", "Android");
urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
urlConnection.addRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.connect();
outputStream = urlConnection.getOutputStream();
HashMap<String, Object> jsonMap = new HashMap<>();
jsonMap.put("name", "foge");
jsonMap.put("value", 100);
ArrayList<String> array = new ArrayList<>();
array.add("Good morning");
array.add("Hello");
array.add("Good evening");
jsonMap.put("array", array);
JSONObject responseJsonObject = new JSONObject(jsonMap);
String jsonText = responseJsonObject.toString();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
bufferedWriter.write(jsonText);
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;
}
}
Recommended Posts