初めに
Androidアプリからリクエストを投げて、GoでWebServerを立てたローカルサーバー上のファイルをダウンロードする
環境
PC Windows10
Android Studio 4.0
Kotlin 1.3.72
Android端末 Emulator(API Level 29)
Go 1.11.1
構成図
Androidアプリからファイル名を指定して、サーバー側にリクエスト、サーバー側に保存されているファイルとステータスコードを返却
実装
ローカルサーバー
package controllers
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
)
func apiSampleHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "POST":
fmt.Println("POST")
case "GET": // GETのリクエストでファイルDL
fmt.Println("GET")
name := fmt.Sprint(r.URL) // 「/ファイル名」を取得
fileName := strings.SplitAfter(name, "/")[1] // 「ファイル名」を取得
// ファイルがサーバー側に存在するかのチェック
if fileinfo, err := os.Stat("./" + fileName); os.IsNotExist(err) || fileinfo.IsDir() {
fmt.Println("file is not exist")
w.WriteHeader(http.StatusNotFound)
return
}
buf, err := ioutil.ReadFile("./" + fileName) // ファイル読み出し
if err != nil {
fmt.Println("file could not be read")
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(buf) // レスポンスに書き込む
}
w.WriteHeader(http.StatusOK)
}
// main.goから呼び出してサーバーを起動
func StartWebServer() error {
http.HandleFunc("/", apiSampleHandler)
return http.ListenAndServe(":8080", nil)
}
main.goを実行し、サーバーを起動
http://localhost:8080 にアクセスして、サーバーが起動していることを確認
ファイルを準備
ダウンロードする用のファイルをmain.goと同じディレクトリに配置
Android アプリ
1.Androidmanifest.xml
インターネットにアクセスするためのPermissionを定義
<uses-permission android:name="android.permission.INTERNET" />
Android 9.0からhttpの通信の設定がOFFになるのでusesCleartextTrafic
をtrueに設定
<application
省略
android:usesCleartextTraffic="true">
<activity android:name=".MainActivity">
省略
</activity>
</application>
2.サーバーアクセス
http通信でサーバーにGETでアクセスする
fun requestFileDownload(context: Context, requestUrl: String, fileName: String): Int {
val url = URL("$requestUrl/$fileName.txt") // URLオブジェクト生成
// UrlConnectionオブジェクト生成
val urlConnection = url.openConnection() as HttpURLConnection
var result = ""
var responseCode = 0
try {
urlConnection.requestMethod = "GET" // POST, GETなど
urlConnection.doInput = true // レスポンスボディの受信
urlConnection.useCaches = false // キャッシュの利用
urlConnection.connect() // コネクションを確立
responseCode = urlConnection.responseCode // レスポンスコードを取得
when (responseCode) {
HttpURLConnection.HTTP_OK -> { // レスポンスコードが200:OKの時だけ処理
val path = context.filesDir.toString() + "/" + fileName + FILE_EXPAND
// レスポンスの内容を読み出す
DataInputStream(urlConnection.inputStream).use { fileInputStream ->
// ファイルを作成し書き込む
DataOutputStream(BufferedOutputStream(FileOutputStream(path))).use {
val buffer = ByteArray(BUFFER_SIZE)
var byteRead: Int
do {
byteRead = fileInputStream.read(buffer)
if (byteRead == -1) {
break
}
it.write(buffer, 0, byteRead)
} while (true)
}
}
}
}
} catch (e: Exception) {
Log.e("Net", "#startConnection$e")
} finally {
urlConnection.disconnect()
}
return responseCode
}
}
3.IPアドレスの確認
アクセスしたいサーバー(PC)のIPアドレスをcommand promptで以下を実行し確認
>ipconfig
4.PCとAndroid端末を同一のネットワーク環境に接続
5.Androidにて接続
Net#requestFileDownloadのrequestUrlにhttp://{確認したIPアドレス}:8080を設定
Net#requestFileDownloadのfileNameにダウンロードするファイル名を設定し実行
ファイルのダウンロードを確認
アプリ固有領域(/data/data/{package_name}/files
配下)にファイルが生成されていることを確認
Device File Explorer でデバイス上のファイルを表示する
最後に
全体ソースはこちら
アクセス先やRequestMethod、ファイル名はアプリで動的に変更できるようにしています。
サーバーへのファイルアップロードはこちら
参考文献
Goサーバー側
Package http
Go言語 (golang) ファイル・ディレクトリの存在チェック
[Golang] ファイル読み込みサンプル