2018/11/15

[Android] Send a Request to Website

Android 要如何傳送檔案要求到網站,本篇用一個開放測試的 Web API (Empath API) 來示範。 Empath 是一個可以透過聲音來辨識情緒的AI,它開放了一個 EmpathAPI 來讓使用者可以測試。
This tutorial is to teach how to develop empath API for Android.
Official Website: https://webempath.com/ 
Developer Website: https://webempath.net/sign_in
1. Sign up an development account for free.
2. Log in to the development page.
3. Go to API Keys and Add a new API Key.

4. Follow the WebAPI Specifications Document to develop.

5. Prepare the proper sound files for testing.
6. Create an Android project.
6.1. Use okhttp3 request tool in Android to send the sound file to the web.
6.2. Insert the endpoint URL and APIKEY apply to the web.
6.3. Get the responses message from the web.

AndroidManifest.xml:
  1. <uses-permission android:name="android.permission.INTERNET"/>
  2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

build.gradle:
  1. dependencies {
  2. ........
  3. implementation 'com.squareup.okhttp3:okhttp:3.9.0' // okhttp
  4. }

MainActivity:
  1. package com.example.chris.myapplication;
  2.  
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.media.MediaPlayer;
  6. import android.net.Uri;
  7. import android.os.AsyncTask;
  8. import android.os.Build;
  9. import android.os.Bundle;
  10. import android.os.Handler;
  11. import android.os.Message;
  12. import android.support.annotation.RequiresApi;
  13. import android.support.v7.app.AppCompatActivity;
  14. import android.util.Log;
  15. import android.view.View;
  16. import android.widget.TextView;
  17. import android.widget.Toast;
  18. import org.json.JSONException;
  19. import org.json.JSONObject;
  20. import java.io.File;
  21. import lib.folderpicker.FolderPicker;
  22. import okhttp3.MediaType;
  23. import okhttp3.MultipartBody;
  24. import okhttp3.OkHttpClient;
  25. import okhttp3.Request;
  26. import okhttp3.RequestBody;
  27. import okhttp3.Response;
  28.  
  29. public class MainActivity extends AppCompatActivity{
  30.  
  31. private String TAG = "MainActivity";
  32.  
  33. private TextView tv_show, tv_filename;
  34.  
  35. private String EMPATH_ENDPOINT = "https://api.webempath.net/v2/analyzeWav";
  36. private String EMPATH_APIKEY = "hi2IaUFb7FUg8CLjBCcF-gubmihVtTgJX4bJcZLHxFE";
  37. private String filePath = "/storage/emulated/0/Empath/";
  38. private String fileName = "sound_01.wav";
  39. private String readFile = "";
  40.  
  41. private Handler handler = null;
  42. private final int MSG_GET_EMOTION = 1010;
  43. private final int MSG_FAIL_GET_EMOTION = 1020;
  44. private final int PICKFILE_RESULT_CODE = 1;
  45.  
  46.  
  47. @Override
  48. protected void onCreate(Bundle savedInstanceState) {
  49. super.onCreate(savedInstanceState);
  50. setContentView(R.layout.activity_main);
  51.  
  52. tv_show = (TextView)findViewById(R.id.id_tv_result);
  53. tv_filename = (TextView)findViewById(R.id.id_tv_filename);
  54.  
  55. readFile = filePath+fileName;
  56.  
  57. handler = new Handler(new Handler.Callback(){
  58. @RequiresApi(api = Build.VERSION_CODES.KITKAT)
  59. @Override
  60. public boolean handleMessage(Message message) {
  61. switch (message.what){
  62. case MSG_GET_EMOTION:
  63. //createSuperTikyuJin((JSONObject)message.obj);
  64. Log.d(TAG, "send success");
  65. break;
  66. case MSG_FAIL_GET_EMOTION:
  67. Toast.makeText(getApplicationContext(), "", Toast.LENGTH_LONG).show();
  68. break;
  69. }
  70. return false;
  71. }
  72. });
  73. }
  74.  
  75. public void onClickPlaySound(View v){
  76. MediaPlayer mp = MediaPlayer.create(this, Uri.parse(readFile));
  77. switch (v.getId()){
  78. case R.id.id_btn_play01:
  79. mp.start();
  80. break;
  81. }
  82. }
  83.  
  84. public void onClickTest(View v){
  85. switch (v.getId()){
  86. case R.id.id_btn_test01:
  87. break;
  88. }
  89. new GetEmotion().execute();
  90. }
  91.  
  92. public void onClickAttachFile(View v){
  93. Intent intent = new Intent(this, FolderPicker.class);
  94. //To show a custom title
  95. intent.putExtra("title", "Select file to upload");
  96.  
  97. //To begin from a selected folder instead of sd card's root folder. Example : Pictures directory
  98. intent.putExtra("location", filePath);
  99.  
  100. //To pick files
  101. intent.putExtra("pickFiles", true);
  102. startActivityForResult(intent, PICKFILE_RESULT_CODE);
  103. }
  104.  
  105. @Override
  106. protected void onActivityResult(int requestCode, int resultCode, Intent intent)
  107. {
  108. if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK) {
  109. String folderLocation = intent.getExtras().getString("data");
  110. tv_filename.setText(folderLocation);
  111. readFile = folderLocation;
  112. }
  113. }
  114.  
  115. private class GetEmotion extends AsyncTask {
  116. private String result = null;
  117. @Override
  118. protected Long doInBackground(String... strings) {
  119. try{
  120. OkHttpClient client = new OkHttpClient();
  121. File file = new File(readFile);
  122. if(file.exists()){
  123. Log.d(TAG,"file load success");
  124. }
  125. else{
  126. Log.d(TAG,"File not found!");
  127. }
  128. RequestBody requestBody = new MultipartBody.Builder()
  129. .setType(MultipartBody.FORM)
  130. .addFormDataPart("apikey", EMPATH_APIKEY)
  131. .addFormDataPart("wav", fileName, RequestBody.create(MediaType.parse("multipart/form-data"), file))
  132. .build();
  133. Request request = new Request.Builder().url(EMPATH_ENDPOINT).post(requestBody).build();
  134. Response response = client.newCall(request).execute();
  135. if(response.isSuccessful()){
  136. Log.d(TAG, "Response success");
  137. }
  138. this.result = response.body().string();
  139. return 0L;
  140. }catch(Exception e){
  141. result = "error";
  142. return 1L;
  143. }
  144. }
  145. @Override
  146. protected void onPostExecute(Long result) {
  147. super.onPostExecute(result);
  148. if (result == 0L){
  149. try {
  150. // get json file
  151. Log.d(TAG, "json: " + this.result);
  152. tv_show.setText("result:" + this.result);
  153. JSONObject json = new JSONObject(this.result);
  154. Message msg = Message.obtain();
  155. msg.what = MSG_GET_EMOTION;
  156. msg.obj = json;
  157. handler.sendMessage(msg);
  158. } catch (JSONException e) {
  159. Message msg = Message.obtain();
  160. msg.what = MSG_FAIL_GET_EMOTION;
  161. handler.sendMessage(msg);
  162. e.printStackTrace();
  163. }
  164. }
  165. }
  166. }
  167. }

activity_main.xml:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context="com.example.chris.myapplication.MainActivity">
  8.  
  9. <TextView
  10. android:id="@+id/id_tv_result"
  11. android:layout_width="348dp"
  12. android:layout_height="86dp"
  13. android:layout_marginStart="4dp"
  14. android:layout_marginTop="168dp"
  15. android:text="Test Sound"
  16. app:layout_constraintStart_toStartOf="parent"
  17. app:layout_constraintTop_toTopOf="parent" />
  18.  
  19. <Button
  20. android:id="@+id/id_btn_play01"
  21. android:layout_width="wrap_content"
  22. android:layout_height="50dp"
  23. android:layout_marginStart="4dp"
  24. android:layout_marginTop="104dp"
  25. android:onClick="onClickPlaySound"
  26. android:text="PLAY"
  27. app:layout_constraintStart_toStartOf="parent"
  28. app:layout_constraintTop_toTopOf="parent" />
  29.  
  30. <Button
  31. android:id="@+id/id_btn_test01"
  32. android:layout_width="wrap_content"
  33. android:layout_height="50dp"
  34. android:layout_marginStart="112dp"
  35. android:layout_marginTop="104dp"
  36. android:onClick="onClickTest"
  37. android:text="TEST"
  38. app:layout_constraintStart_toStartOf="parent"
  39. app:layout_constraintTop_toTopOf="parent" />
  40.  
  41. <Button
  42. android:id="@+id/id_btn_attach"
  43. android:layout_width="wrap_content"
  44. android:layout_height="49dp"
  45. android:layout_marginStart="4dp"
  46. android:layout_marginTop="4dp"
  47. android:onClick="onClickAttachFile"
  48. android:text="file"
  49. app:layout_constraintStart_toStartOf="parent"
  50. app:layout_constraintTop_toTopOf="parent" />
  51.  
  52. <TextView
  53. android:id="@+id/id_tv_filename"
  54. android:layout_width="wrap_content"
  55. android:layout_height="wrap_content"
  56. android:layout_marginStart="4dp"
  57. android:layout_marginTop="60dp"
  58. android:text="TextView"
  59. app:layout_constraintStart_toStartOf="parent"
  60. app:layout_constraintTop_toTopOf="parent" />
  61.  
  62. </android.support.constraint.ConstraintLayout>
  63.  

APP執行結果:


END

沒有留言:

張貼留言