0

Android アプリでダウンロードを行っていますが、ダウンロードされた割合を表示するために content_length を取得する必要があります。

ファイルは、クライアントがセットアップしたサーバー上にあります。このサーバーでは、getContentLength() を呼び出すと -1 が返されます。ヘッダーは次のとおりです。

THIS SERVERS HEADER DOESN'T WORK WITH urlConnection.getContentLength()


    $ curl --head "http://www.server0.com/ango/thefile.m4v"
    HTTP/1.1 200 OK
    Set-Cookie: JSESSIONID=A17762C6B65FD8D35840110F8628DE4B.V5; Path=/; HttpOnly
    X-ServedBy: web114
    Set-Cookie: SS_MID=7315b0cb-054c-4dd8-a013-c7163793becehfjcndg8; Domain=.tangoberretin.com; Expires=Thu, 13-Apr-2023 07:57:07 GMT; Path=/
    Pragma: cache
    Cache-Control: private,max-age=86400
    Last-Modified: Thu, 21 Feb 2013 06:28:24 GMT
    Content-Disposition: attachment; filename="thefile.m4v";
    Accept-Ranges: bytes
    Content-Range: bytes 0-6716578/6716579
    Content-Type: application/octet-stream;charset=UTF-8
    Content-Length: 6716579
    Date: Mon, 15 Apr 2013 07:57:07 GMT
    Server: SSWS
    Set-Cookie: WebPersCookie=Gn5lN9r2EIK+3eKz0tv/bEs4IJpcBzYg22jKvv/JD1eAA1N3D0pevaz3zuXOD3uTT950AQdstGRJgdE=; path=/

そこで、テストを行い、ファイルを自分のサーバー (apache) に置いたところ、すべて正常に動作しました。これらのヘッダーは次のとおりです。

THIS SERVERS HEADER WORKS WITH urlConnection.getContentLength()


    $ curl --head "http://server1.net/wp-content/video/thefile.m4v"
    HTTP/1.1 200 OK
    Date: Mon, 15 Apr 2013 07:57:42 GMT
    Server: Apache
    Last-Modified: Sun, 14 Apr 2013 23:49:00 GMT
    Accept-Ranges: bytes
    Content-Length: 502365
    Content-Type: text/plain

だから私の質問は、最初のケースが失敗の原因であり、それに対して何ができるかということです. 理想的には、ファイルをそのままにしておきます。

*更新* *

Android アプリからヘッダーを出力しましたが、どうやらサーバーが Android エージェントの Content-Length を送信していないようです。理解できない... :(

HTTP/1.1 200 OK
Accept-Ranges : 
bytes
Cache-Control : 
private,max-age=86400
Content-Disposition : 
attachment; filename="04Left_Turning_Check_Step.m4v";
Content-Range : 
bytes 0-7019776/7019777
Content-Type : 
application/octet-stream;charset=UTF-8
Date : 
Mon, 15 Apr 2013 08:39:06 GMT
Last-Modified : 
Wed, 02 Jan 2013 18:40:09 GMT
Pragma : 
cache
Server : 
SSWS
Set-Cookie : 
JSESSIONID=0B1D0CFFD975ED2736BFF7BBC23ACD96.V5; Path=/; HttpOnly
SS_MID=5a7bd305-4ac1-4d4d-98a3-67fa26c0db56hfje5d3d; Domain=.tangoberretin.com; Expires=Thu, 13-Apr-2023 08:39:06 GMT; Path=/
WebPersCookie=WIo8mRMTANAAke3GEsDOsONkGZoRcVvqpC4Am/pl/3WFB9hSEGH5DfGiDSKJDLc2nbZBpWFy3/Yfb3s=; path=/
Transfer-Encoding : 
chunked
Vary : 
Accept-Encoding
X-Android-Received-Millis : 
1366015147201
X-Android-Sent-Millis : 
1366015146842
X-ServedBy : 
web115
4

2 に答える 2

1

ここで重要なことは次のとおりです。

Transfer-Encoding : 
chunked

チャンク転送エンコーディングについては、こちらで説明しています。

簡単に言えば、チャンク転送エンコーディングを使用すると、サーバーは、送信前にコンテンツのサイズを決定する必要なく、一連のチャンクで大きなコンテンツを送信できます。これにより、サーバーは、コンテンツをクライアントに送信するためにストレージからコンテンツをロードする方法について、はるかに効率的になります。

クライアントと話し、サーバーが応答ヘッダーで有効で正確な Content-Length を提供する場合は進捗レポートを提供できるが、そうでない場合は提供できないことを伝える必要があると思います。または、コンテンツに関する情報 (コンテンツのサイズを含む) を取得する最初のリクエストを作成してから、コンテンツ自体の 2 番目のリクエストを作成することはできますか? その場合は、進捗レポートを提供できます。

于 2013-04-15T10:51:55.460 に答える
0

古い投稿ですが、マークによる説明は私の解決策を教えてくれました。


次の呼び出しを使用して URL を呼び出します。これにより、サーバーが「チャンク」モードにならずにコンテンツの長さを返すことができます。

DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse execute = client.execute(httpGet);
int contentLength = (int)execute.getEntity().getContentLength();

その後、URLConnection を使用してリクエストを再作成し、すでに返されたコンテンツの長さを計算に使用できます。

于 2013-12-06T11:35:23.410 に答える