Genta Hirauchi

公開日:2020/06/02
更新日:2020/08/03

【Kotlin】HttpURLConnectionで、HTTP通信を行う方法を解説

  • サーバー上のファイルをダウンロードする方法が知りたい。
  • HttpURLConnectionによる通信処理がうまくいかない。

サーバー上のファイルをダウンロードは、HttpURLConnectionによるHTTP通信処理を実装することで実現することができます。

本記事では、Macのローカル環境にサーバーを立ち上げる方法と、HTTP通信処理の実装、そして、自分がHttpURLConnectionによるHTTP通信処理を実装する上で発生した問題の解決方法について紹介しております。

目次

ローカルにサーバーを立ち上げる

今回紹介するHTTP通信処理は、ローカル上にサーバーを立ち上げ、localhostにアップロードした動画ファイルのダウンロードを行う形で紹介したいと思います。

自分が使用しているPCはMacですので、Apacheを起動し、サーバー環境を構築致します。

詳しくは、以下の記事をご覧ください。

【Kotlin】MacのlocalhostにAndroid端末から接続する方法を解説

サーバーとの通信処理を実装する際、実際に使用されているサーバーを使用してするのではなく、まずはローカル環境にサーバーを構築して実装を進めると思います。本記事では、Macのローカル環境にサーバーを立ち上げる方法と、Androidの実機、およびEmulatorから、localhostにアクセスする方法について解説致します。

HttpURLConnectionで、サーバー上の動画をダウンロードする

権限の追加

HTTP通信処理を実装するにあたり、ネットワーク、及びファイルの読み書きに関する権限を追加します。

AndroidManifestに、以下を追加します。

上から順に、ネットワーク、ファイルのRead、ファイルのWriteに関する権限です。

なお、ファイルの読み書きに関する権限は、アプリでシステムダイアログを表示し、ユーザーに権限の許可を問う処理を実装する必要がありますが、今回はその実装を割愛させて頂きます。

本記事の処理を実装後、HTTP通信がうまくいかなかった場合は、端末の設定から、開発中のアプリを選択しのストレージの権限がOFFになっていないかをご確認ください。

HTTP通信処理の実装

続いて、HttpURLConnectionによるHTTP通信処理の実装方法について解説致します。

HttpTaskというクラスに、HTTP通信処理を実装していきます。

HttpURLConnectionによるHTTP通信処理は、非同期で実装する必要があるため、HttpTaskクラスは、AsyncTaskを継承しております。

doInBackground()の引数には、通信先のURLが渡ってくることを想定しております。

10行目のopenConnection()で、HttpURLConnectionのインスタンスを取得し、connect()で接続を行なっております。

接続がうまくいくと、responseCodeに200が返ってきます。HttpURLConnection.HTTP_OKは、200の定数です。

15、16行目では、ファイルの読み書きを行うためのStreamを取得しております。

18〜23行目では、サーバー上のファイルの読み込みと、ローカルのファイルへの書き出しを行なっております。

readで4096byteずつデータを読み込み、読み込んだデータをwriteで書き出しております。

これ以上読み込むデータがなくなると、readは-1を返します。-1が返されるまで、whileで読み込み&書き出しを繰り返すように実装しております。

上記の処理が終了すると、Streamをclose()で閉じます。

そして、最後にfinally{}が呼ばれ、HttpURLConnectionをdisconnect()します。

API28以上で接続に失敗する問題について

HttpURLConnectionのconnect()関数を呼び出した際に、java.io.IOException: Cleartext HTTP traffic to 10.0.2.2 not permittedのようなエラーが発生することがあります。

APIレベルが28以上では、クリアテキストのサポートがデフォルトで無効になっているため、このようなエラーが発生いたします。

問題を解決するには、AndroidManifestに以下を追加します。

HttpURLConnectionによる、HTTP通信処理の実装方法の解説は以上となります。ありがとうございました。