アップロード オプション
Android Over The Air API を使用すると、パッケージ データをアップロードして新しい Package リソースを作成できます。これらは 1 つ以上の設定と関連付けてアップデートを配信することができる OTA パッケージ 提供します。
Google では、再開可能なパッケージ アップロードを容易にする Linux 用と Windows 用のバイナリを提供しており、 以下で説明するプロトコルを実装する代わりに、 を自由に使用できます。より深いレベルで 下記のいずれかのプロトコルを使用してください。
Linux
Linux 用 Android Over The Air API v1 アップローダ クライアントをダウンロードします。
Windows
Windows 用 Android Over The Air API v1 アップローダ クライアントをダウンロードします。
これを使用するには、まずサービス アカウントを作成し、そのアカウント用の JSON キーファイルを取得する必要があります。
アカウント作成のガイドについては、こちらをご覧ください。
バイナリと鍵ファイルを入手したら、コマンドライン オプションを使用して実行し、
鍵ファイル、デプロイメント、アップロードするパッケージを指定します。--help
を使用してください
すべてのオプションを表示します。
アップロードのプロトコル
アップロード リクエストは次のいずれかの方法で行うことができます。
使用する方法は、X-Goog-Upload-Protocol
リクエスト ヘッダーで指定します。
- マルチパート アップロード(
X-Goog-Upload-Protocol: multipart
)。データを 小さなファイルとメタデータファイルとそのファイルを記述するメタデータのすべてを 1 つのリクエストで転送します。 - 再開可能アップロード(
X-Goog-Upload-Protocol: resumable
)。大規模なデータセットで特に重要な、信頼性の高い転送を実現 できます。このメソッドでは、セッション開始リクエストを使用します。オプションでメタデータを含めることができます。これはほとんどの組織にとって アップロードごとに HTTP リクエストを 1 つ追加する手間を要しますが、比較的小さいファイルでも機能します。
マルチパート アップロード
送信するデータが小さい場合に適しています アップロードできるように、十分な余裕を持たせてください。
マルチパート アップロードを使用するには、/upload/package に POST
リクエストを送信します。
URI を指定し、X-Goog-Upload-Protocol
を multipart
に設定します。
マルチパート アップロード リクエストを作成するときに使用する最上位 HTTP ヘッダーには、以下を含めます。
Content-Type
。multipart/related に設定し、対象境界文字列を含めます。 リクエストの各部分を識別できます。Content-Length
。リクエスト本文の総バイト数に設定します。
リクエストの本文は、multipart/related
コンテンツの形式になります。
タイプ [RFC2387] であり、厳密に 2 つの部分を含みます。
各部分は境界文字列で区別され、最後の境界文字列には後に 2 つのハイフンが続きます。
マルチパート リクエストの各部分には、次の Content-Type
ヘッダーを追加する必要があります。
- メタデータ パート: 最初に配置する必要があります。
Content-Type
はapplication/json
にする必要があります。 - メディアパート: 2 番目に配置する必要があります。
Content-Type
はapplication/zip
にする必要があります。
例: マルチパート アップロード
Android Over The Air API のマルチパート アップロード リクエストの例を次に示します。
POST /upload/package HTTP/1.1 Host: androidovertheair.googleapis.com Authorization: Bearer your_auth_token Content-Type: multipart/related; boundary=BOUNDARY Content-Length: number_of_bytes_in_entire_request_body --BOUNDARY Content-Type: application/json; charset=UTF-8 {"deployment": "id", "package_title": "title" } --BOUNDARY Content-Type: application/zip; charset=UTF-8 Package ZIP --BOUNDARY--
リクエストが成功すると、サーバーは HTTP 200 OK
ステータス コードを返します。
HTTP/1.1 200
これを簡単に行うには、curl を使用します。 および oauth2l です。以下はリクエストのサンプルです。 サービスキーを使用していることを前提としています( 認証方法をご確認ください)。
curl リクエストの例
JSON={"deployment": "id", "package_title": "title" } SERVICE_KEY_FILE=path to your service key json file curl \ -H "$(./oauth2l header --json $SERVICE_KEY_FILE android_partner_over_the_air)" \ -H "Host: androidovertheair.googleapis.com" \ -H "X-Goog-Upload-Protocol: multipart" \ -H "Content-Type: multipart/form-data" \ -F "json=$JSON;type=application/json" \ -F "data=@update.zip;type=application/zip" \ androidovertheair.googleapis.com/upload/package
再開可能アップロード
より信頼性の高い方法でデータファイルをアップロードするには、再開可能なアップロード プロトコルを使用します。このプロトコルにより、 通信障害でデータの送信が中断されても、アップロード操作を再開できます。これは、 大容量のファイルを転送する場合や、ネットワークが中断する可能性がある場合に特に便利です。 モバイル クライアント アプリからアップロードする場合などに、その他の送信エラーが頻繁に発生することがあります。これは、 また、ネットワーク障害が発生した場合の帯域幅の使用量も削減できます。 大きなファイルのアップロードを最初からやり直す必要があります。
再開可能アップロードのプロトコルでは、いくつかのコマンドを使用します。
- 再開可能なセッションを開始します。次の URL を含むアップロード URI に最初のリクエストを送信します。 一意の再開可能なアップロード場所を確立します。
- 再開可能なセッション URI を保存します。URL で返されたセッション URI を 最初のリクエストのレスポンス。このセッションの残りのリクエストに使用します。
- ファイルをアップロードします。ZIP ファイルの全体または一部を再開可能なセッション URI に送信します。
また、再開可能なアップロードを使用するアプリには、中断したアップロードを再開するためのコードが必要です。アップロードが 正常に受信されたデータの量を確認し、その時点からアップロードを再開します。
注: アップロード URI は 3 日後に期限切れになります。
手順 1: 再開可能なセッションを開始する
再開可能なアップロードを開始するには、/upload/package に POST
リクエストを送信します。
URI を指定し、X-Goog-Upload-Protocol
を resumable
に設定します。
この最初のリクエストの本文にはメタデータのみを含める必要があります。実際の 後続のリクエストでアップロードするファイルの内容を指定します。
最初のリクエストでは、次の HTTP ヘッダーを使用します。X-Goog-Upload-Header-Content-Type
。アップロードするファイルのコンテンツ タイプで、application/zip
に設定する必要があります。X-Goog-Upload-Command
。start
に設定X-Goog-Upload-Header-Content-Length
。後続のリクエストで転送するアップロード データのバイト数に設定します。 このリクエストの時点で長さが不明な場合は、このヘッダーを省略できます。Content-Type
。これはメタデータのコンテンツ タイプで、application/json
に設定する必要があります。Content-Length
。最初のリクエストの本文で送信するバイト数に設定します。
例: 再開可能なセッション開始リクエスト
次の例は、Android Over The Air API の再開可能セッションを開始する方法を示しています。
POST /upload/package HTTP/1.1 Host: android/over-the-air.googleapis.com Authorization: Bearer your_auth_token Content-Length: 38 Content-Type: application/json; charset=UTF-8 X-Goog-Upload-Command: start X-Goog-Upload-Header-Content-Type: application/zip X-Goog-Upload-Header-Content-Length: 2000000 {"deployment": "id", "package_title": "title" }
次に、レスポンスの処理方法について説明します。
手順 2:再開可能なセッション URI を保存する
セッション開始リクエストが成功すると、API サーバーは HTTP 200 OK
ステータス コードを返します。
また、再開可能セッション URI を指定する X-Goog-Upload-URL
ヘッダーも返します。
次の例の X-Goog-Upload-URL
ヘッダーには、upload_id
クエリ パラメータが含まれています。
このセッションで使用する一意のアップロード ID を指定する部分です。レスポンスには X-Goog-Upload-Status
も含まれます。
ヘッダー。アップロード リクエストが有効で受け入れられた場合は active
になります。このステータスは final
の可能性があります。
エラーが表示されます
例: 再開可能なセッション開始のレスポンス
ステップ 1 のリクエストに対するレスポンスは次のとおりです。
HTTP/1.1 200 OK X-Goog-Upload-Status: active X-Goog-Upload-URL: androidovertheair.googleapis.com/?upload_id=xa298sd_sdlkj2 Content-Length: 0
上のレスポンス例に示されている X-Goog-Upload-URL
ヘッダーの値は、次のようになります。
このセッション URI は、実際にファイルをアップロードしたり、アップロード ステータスをクエリしたりするための HTTP エンドポイントとして使用します。
後続のリクエストで使用できるように、セッション URI をコピーして保存します。
ステップ 3: ファイルをアップロードする
ファイルをアップロードするには、POST
リクエストを
確認できます。アップロード リクエストの形式は次のとおりです。
POST session_uri
再開可能なファイル アップロードのリクエストを作成するときに使用する HTTP ヘッダーの内容は次のとおりです。
Content-Length
。この値は、このリクエストでアップロードするバイト数(通常はアップロード ファイルのサイズ)に設定します。X-Goog-Upload-Command
。upload
とfinalize
に設定します。X-Goog-Upload-Offset
。これは、バイトが書き込まれるオフセットを指定しています。なお、クライアントは バイトを順番にアップロードする必要があります。
例: 再開可能なファイル アップロード リクエスト
この例で 2,000,000 バイトの ZIP ファイル全体をアップロードする再開可能なリクエストは次のとおりです。
POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1 Host: androidovertheair.googleapis.com X-Goog-Upload-Protocol: resumable X-Goog-Upload-Command: upload, finalize X-Goog-Upload-Offset: 0 Content-Length: 2000000 Content-Type: application/zip bytes 0-1999999
リクエストが成功すると、サーバーは HTTP 200 Ok
を返します。
アップロード リクエストが中断された場合や、HTTP 503 Service Unavailable
などのエラーが発生した場合
他の 5xx
レスポンスがサーバーから返された場合は、中断されたアップロードを再開するに記載されている手順に沿って操作してください。
チャンク形式でファイルをアップロードする
再開可能なアップロードでは、ファイルをチャンクに分割し、一連のリクエストを送信して各チャンクを順番にアップロードできます。
この方法は推奨されません。リクエスト数の増加に伴ってパフォーマンス コストがかかります。また、
通常は不要です。クライアントには、ペイロードの残りのバイトをすべてアップロードし、
すべての upload
コマンドに finalize
コマンドを含めます。
ただし、分割を使用して転送するデータの量を減らす 単一リクエスト。また、従来のブラウザでアップロードの進行状況を表示することもできます。 アップロードの進行状況をサポートしていません
中断されたアップロードを再開する
レスポンスを受信する前にアップロード リクエストが終了した場合や、
サーバーから HTTP 503 Service Unavailable
レスポンスが返された場合は、中断されたアップロードを再開する必要があります。手順は次のとおりです。
- ステータスをリクエストする。アップロード URI にリクエストを発行して、アップロードの現在のステータスをクエリする
X-Goog-Upload-Command
をquery
に設定します。注: アップロードが中断された場合でなくても、チャンク間のステータスをリクエストできます。これは、 たとえば、従来のブラウザでアップロードの進行状況を表示したい場合に役立ちます。
- アップロードされたバイト数を取得する。ステータス クエリからのレスポンスを処理します。このサーバーは
レスポンスの
X-Goog-Upload-Size-Received
ヘッダー。これまでに受信したバイト数を指定します。 - 残りのデータをアップロードする。リクエストの再開ポイントがわかったので、最後に
残りのデータまたは現在のチャンクに分割されますいずれの場合も残りのデータを個別のチャンクとして扱う必要があります。
アップロードを再開するときに、
X-Goog-Upload-Offset
ヘッダーを適切なオフセットに設定する必要があります。
例: 中断されたアップロードを再開する
1)アップロード ステータスをリクエストします。
POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1 Host: androidovertheair.googleapis.com X-Goog-Upload-Command: query
すべてのコマンドと同様に、クライアントはクエリコマンドの HTTP レスポンスの X-Goog-Upload-Status
ヘッダーを確認する必要があります。
ヘッダーが存在し、値が active
でない場合、アップロードはすでに終了しています。
2)レスポンスから、これまでにアップロードされたバイト数を抽出します。
サーバーのレスポンスでは、X-Goog-Upload-Size-Received
ヘッダーを使用して、
ファイルの最初の 43 バイトを受信しました。
HTTP/1.1 200 OK X-Goog-Upload-Status: active X-Goog-Upload-Size-Received: 42
3)中断された位置からアップロードを再開します。
次のリクエストは、ファイルの 43 番目以降の残りのバイトを送信して、アップロードを再開します。
POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1 Host: androidovertheair.googleapis.com X-Goog-Upload-Command: upload, finalize Content-Length: 1999957 X-Goog-Upload-Offset: 43 bytes 43-1999999
おすすめの方法
メディアをアップロードするときは、エラー処理に関連するいくつかのおすすめの方法を知っておくと便利です。
- 接続の中断や次のような
5xx
エラーが原因で失敗したアップロードは、再開または再試行してください。500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- アップロードの再開または再試行のリクエスト時に
5xx
サーバーエラーが返された場合は、指数バックオフ戦略を使用します。こうしたエラーは、サーバーに負荷がかかりすぎているときに発生することがあります。指数バックオフは、大量のリクエストまたは大量のネットワーク トラフィックが発生しているときに、この種の問題の軽減に役立ちます。 - その他の種類のリクエストは指数バックオフでは処理できませんが、多数のリクエストは再試行できます。リクエストを再試行するときは、再試行の回数を制限します。たとえば、コードで再試行回数を 10 回に制限し、それを超えるとエラーが報告されるようにします。
- 再開可能なアップロードで
404 Not Found
エラーが発生した場合には、最初から全体のアップロードをやり直します。
指数バックオフ
指数バックオフは、ネットワーク アプリケーションの標準的なエラー処理方法で、クライアントはリクエスト間の遅延を増加させながら、失敗したリクエストを定期的に再試行します。大量のリクエストまたは大量のネットワーク トラフィックが原因でサーバーがエラーを返した場合、指数バックオフはこのようなエラーの処理に適した方法です。逆に、承認認証情報が無効である、ファイルが見つからないなど、ネットワークのボリュームまたはレスポンス タイムに関係のないエラーの処理には適していません。
指数バックオフを適切に使用すると、帯域幅の使用効率が高くなり、より少ないリクエスト数で正常なレスポンスを受け取ることができ、同時実行環境でのリクエストのスループットが最大化します。
シンプルな指数バックオフを実装するフローは次のとおりです。
- API へのリクエストを作成します。
- リクエストの再試行が必要であることを示す
HTTP 503
レスポンスを受信します。 - 1 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
- リクエストの再試行が必要であることを示す
HTTP 503
レスポンスを受信します。 - 2 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
- リクエストの再試行が必要であることを示す
HTTP 503
レスポンスを受信します。 - 4 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
- リクエストの再試行が必要であることを示す
HTTP 503
レスポンスを受信します。 - 8 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
- リクエストの再試行が必要であることを示す
HTTP 503
レスポンスを受信します。 - 16 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
- フローを停止します。エラーをレポートまたはログに記録します。
上記のフローで、random_number_milliseconds は、1,000 ミリ秒以下の乱数です。ランダムな遅延を少し加えると、負荷がより均等に分散され、サーバーに負荷がかかる可能性があるため、これが必要となります。random_number_milliseconds の値は、待機するたびに再定義する必要があります。
注: 待機時間は常に (2 ^ n) + random_number_milliseconds(n は 0 から始まる単調増加整数)です。整数 n は、繰り返し(リクエスト)のたびに 1 ずつ増えます。
このアルゴリズムは、n が 5 になると終了するように設定されています。この上限によって、クライアントが無限に再試行を繰り返すことを防ぎます。総遅延時間が約 32 秒になると、リクエストは「回復不能なエラー」と判断されます。再試行の最大回数を増やすこともできます(特に、長いアップロードを行う場合)。ただし、再試行の遅延時間には合理的な上限を設定してください(たとえば 1 分未満)。