アプリケーションで使用する画像ファイルやデータをサーバーに置いて必要に応じてダウンロードすることはよくあります。ただ毎回ダウンロードする必要がないものもあります。そのような場合にはHTTPレスポンスヘッダの最終更新日時Last-Modified
の値を参照して更新するかどうかを判定すればよいでしょう。
本記事ではAndroid+JavaでHTTPレスポンスヘッダのLast-Modifiedの値を取得する方法を紹介します。
(当然ですが)サーバーによってはLast-Modified
を返さないものがあります。例えば、Dropboxはpublicフォルダを使うと不特定多数にファイルを公開することができるのですが、レスポンスヘッダーにLast-Modifiedフィールドが含まれていないので当該のファイルがいつ更新されたかどうかがわからなかったりします。
下記のサンプルコードでは、Amazon Web Services(AWS)のAmazon Simple Storage Service(Amazon S3)上にjsonファイルを置いています。S3から返ってくるレスポンスヘッダーは以下の通りです。
null:[HTTP/1.1 200 OK] Accept-Ranges:[bytes] Content-Length:[43801] Content-Type:[application/json] Date:[Sat, 27 Jun 2015 06:39:57 GMT] ETag:["26ce9"] Last-Modified:[Fri, 26 Jun 2015 06:16:45 GMT] Server:[AmazonS3] x-amz-id-2:[SGig] x-amz-request-id:[BC4] X-Android-Received-Millis:[1435387] X-Android-Sent-Millis:[1435387]
上記のうち使用するのは、
Last-Modified:[Fri, 26 Jun 2015 06:16:45 GMT]
の部分ですね。HttpURLConnectionクラス
を使ってリクエストを送り、レスポンスヘッダーの中からLast-Modified
を読みます。
文字列の最終更新日時を取得することができると思うので、SimpleDateFormatクラス
を使ってDate型に変換しています。
URL url = new URL("https://s3-ap-northeast-1.amazonaws.com/example.jp/hoge.json"); HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); // 最終更新日時の文字列を取得する String lastModified = urlConnection.getHeaderField("Last-Modified"); // それをDate型に変換します Date lastModifiedDate = null; try { SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE',' dd' 'MMM' 'yyyy HH':'mm':'ss zzz", Locale.US); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormatter.setCalendar(new GregorianCalendar()); lastModifiedDate = dateFormatter.parse(lastModified); } catch (ParseException e) { } // あとはlastModifiedDateを比較して更新するかどうかを決める
あとはアプリ内で格納していた前回更新した日時とlastModifiedDateの日時とを比較して後続の処理をおこなうかどうかを決定すれば良いと思います。
If-Modified-Since
に関してはまた元気があるときにでも。
追記(2015.10.22)
汎用的に日付型をパースできるするためのメソッドにしました。