Options d'importation
L'API Android Over The Air vous permet d'importer des données de package afin de créer une ressource Package. Il s'agit Packages OTA pouvant être associés à une ou plusieurs configurations afin de distribuer la mise à jour aux appareils.
Nous fournissons un binaire pour Linux et Windows afin de faciliter les importations de packages avec reprise que vous sont sans frais à utiliser au lieu de mettre en œuvre les protocoles décrits ci-dessous. Si vous souhaitez en savoir plus veuillez utiliser l'un des protocoles décrits ci-dessous.
Linux
Téléchargez le client d'importation version 1 de l'API Android Over The Air pour Linux.
Windows
Téléchargez le client de téléchargement de l'API Android Over The Air version 1 pour Windows.
Pour l'utiliser, vous devez d'abord créer un compte de service et obtenir un fichier de clé JSON pour ce compte.
Veuillez consulter notre guide de création d'un compte.
Une fois que vous disposez du binaire et du fichier de clé, vous pouvez l'exécuter avec des options de ligne de commande pour spécifier
le fichier de clé, votre déploiement et le package que vous importez. Veuillez utiliser --help
pour voir toutes les options.
Protocoles d'importation
Vous pouvez effectuer des requêtes d'importation via l'une des méthodes exposées ci-dessous.
Spécifiez la méthode que vous utilisez avec l'en-tête de requête X-Goog-Upload-Protocol
.
- Importation en plusieurs parties :
X-Goog-Upload-Protocol: multipart
. Pour transférer rapidement des fichiers et des métadonnées plus petits ; transfère le fichier ainsi que les métadonnées qui le décrivent, le tout dans une seule requête. - Importation avec reprise :
X-Goog-Upload-Protocol: resumable
. Pour un transfert fiable, ce qui est particulièrement important avec . Avec cette méthode, vous utilisez une requête de lancement de session qui peut éventuellement inclure des métadonnées. C'est une bonne stratégie à utiliser pour la plupart applications, car il fonctionne également pour des fichiers plus petits au prix d'une requête HTTP supplémentaire par importation.
Importation en plusieurs parties
C'est un bon choix si les données que vous envoyez sont de petite taille pour le réimporter dans son intégralité en cas d'échec de la connexion.
Pour utiliser l'importation en plusieurs parties, envoyez une requête POST
à la commande /upload/package
URI et définissez X-Goog-Upload-Protocol
sur multipart
.
Les en-têtes HTTP de premier niveau à utiliser lors d'une importation en plusieurs parties incluent :
Content-Type
Défini sur "multipart/related" et inclut la chaîne de délimitation utilise pour identifier les parties de la demande.Content-Length
. Défini sur le nombre total d'octets dans le corps de la requête.
Le corps de la requête est mis en forme en tant que contenu multipart/related
.
type [RFC2387] et contient exactement deux parties.
Les parties sont identifiées par une chaîne de délimitation et la dernière chaîne est suivie de deux traits d'union.
Chaque partie de la requête en plusieurs parties nécessite un en-tête Content-Type
supplémentaire :
- Partie de métadonnées:doit apparaître en premier, et
Content-Type
doit êtreapplication/json
. - Partie multimédia:doit apparaître en deuxième, et
Content-Type
doit êtreapplication/zip
.
Exemple : Importation en plusieurs parties
L'exemple ci-dessous illustre une requête d'importation en plusieurs parties pour l'API Android Over The Air.
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--
Si la requête aboutit, le serveur affiche le code d'état HTTP 200 OK
.
HTTP/1.1 200
Pour ce faire, vous pouvez utiliser curl et oauth2l. Voici un exemple de requête qui suppose que vous utilisez une clé de service (consultez notre procédure d'autorisation.
Exemple de requête 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
Importation avec reprise
Pour importer des fichiers de données de manière plus fiable, vous pouvez utiliser le protocole d'importation avec reprise. Ce protocole permet de reprendre une opération d'importation après un échec de communication ayant interrompu le flux de données. Il est particulièrement utile si vous transférez des fichiers volumineux et que le risque d'interruption du réseau ou un autre échec de transmission est élevé, par exemple lors d'une importation à partir d'une application cliente mobile. Il peut également réduire l'utilisation de la bande passante en cas de défaillance du réseau, car vous n'avez pas à relancer les importations de fichiers volumineux depuis le début.
Le protocole d'importation avec reprise utilise plusieurs commandes:
- Démarrez une session avec reprise. Envoyez une requête initiale à l'URI d'importation qui inclut le paramètre et établit un emplacement unique d'importation avec reprise.
- Enregistrez l'URI de la session avec reprise. Enregistrez l'URI de la session renvoyé dans le la réponse à la demande initiale ; vous l'utiliserez pour les requêtes restantes dans cette session.
- Importez le fichier. Envoyez tout ou partie du fichier ZIP à l'URI de la session avec reprise.
En outre, les applications qui utilisent l'importation avec reprise doivent posséder un code pour reprendre une importation interrompue. Si une importation est interrompue, déterminer la quantité de données reçues, puis reprendre l'importation à partir de ce point.
Remarque : Une URI d'importation expire au bout de trois jours.
Étape 1 : Démarrez une session avec reprise
Pour lancer une importation avec reprise, envoyez une requête POST
à /upload/package
URI et définissez X-Goog-Upload-Protocol
sur resumable
.
Pour cette requête de lancement, le corps ne doit contenir que les métadonnées ; vous transférez les véritables du fichier que vous souhaitez importer dans les requêtes ultérieures.
Utilisez les en-têtes HTTP suivants avec la requête initiale :X-Goog-Upload-Header-Content-Type
Type de contenu du fichier en cours d'importation. Il doit être défini surapplication/zip
.X-Goog-Upload-Command
Définir surstart
X-Goog-Upload-Header-Content-Length
. Définissez le nombre d'octets des données d'importation à transférer dans les requêtes ultérieures. Si cette valeur est inconnue au moment de cette requête, vous pouvez omettre cet en-tête.Content-Type
Il s'agit du type de contenu des métadonnées. Il doit être défini surapplication/json
.Content-Length
. Définissez le nombre d'octets fournis dans le corps de cette requête initiale.
Exemple : Requête de lancement de session avec reprise
L'exemple suivant montre comment lancer une session avec reprise pour l'API Android Over The Air.
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" }
La section suivante décrit comment gérer la réponse.
Étape 2 : Enregistrez l'URI de la session avec reprise
Si la requête de lancement de session aboutit, le serveur d'API répond par un code d'état HTTP 200 OK
.
En outre, il fournit un en-tête X-Goog-Upload-URL
qui spécifie votre URI de session avec reprise.
L'en-tête X-Goog-Upload-URL
, illustré dans l'exemple ci-dessous, inclut un paramètre de requête upload_id
.
qui donne l'ID d'importation unique à utiliser pour cette session. La réponse contient également un X-Goog-Upload-Status
qui sera active
si la requête d'importation était valide et acceptée. Cet état peut être final
si l'importation a été refusée.
Exemple : Réponse de lancement de session avec reprise
La réponse à la requête de l'étape 1 se présente comme suit :
HTTP/1.1 200 OK X-Goog-Upload-Status: active X-Goog-Upload-URL: androidovertheair.googleapis.com/?upload_id=xa298sd_sdlkj2 Content-Length: 0
La valeur de l'en-tête X-Goog-Upload-URL
, comme indiqué dans l'exemple de réponse ci-dessus, est
l'URI de session que vous utiliserez comme point de terminaison HTTP pour effectuer l'importation réelle du fichier ou interroger l'état de l'importation.
Copiez et enregistrez l'URI de la session afin de pouvoir l'utiliser pour les requêtes ultérieures.
Étape 3 : Importez le fichier
Pour importer le fichier, envoyez une requête POST
à l'URI d'importation obtenu dans la
à l'étape précédente. Le format de la requête d'importation se présente comme suit :
POST session_uri
Les en-têtes HTTP à utiliser lors des requêtes d'importation de fichiers avec reprise incluent:
Content-Length
Définissez ce paramètre sur le nombre d'octets que vous importez dans cette requête, qui correspond généralement à la taille du fichier d'importation.X-Goog-Upload-Command
Définissez cette valeur surupload
etfinalize
.X-Goog-Upload-Offset
Indique le décalage auquel les octets doivent être écrits. Notez que les clients doit importer des octets en série.
Exemple : Requête d'importation de fichier avec reprise
Voici une requête avec reprise permettant d'importer l'intégralité du fichier ZIP de 2 000 000 octets pour l'exemple actuel.
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
Si la requête aboutit, le serveur envoie une réponse HTTP 200 Ok
.
Si la requête d'importation est interrompue ou si vous recevez un appel HTTP 503 Service Unavailable
ou une
autre réponse 5xx
du serveur, suivez la procédure décrite dans la section Reprendre une importation interrompue.
Importer un fichier fragmenté
Les importations avec reprise vous permettent de diviser un fichier en plusieurs fragments et d'envoyer une série de requêtes afin d'importer chacun de ces fragments l'un après l'autre.
Ce n'est pas l'approche privilégiée, car les requêtes supplémentaires entraînent des coûts de performances.
qui ne sont généralement pas nécessaires. Nous recommandons aux clients de télécharger
tous les octets restants de la charge utile et
incluez la commande finalize
dans chaque commande upload
.
Cependant, vous devrez peut-être recourir à la fragmentation pour réduire la quantité de données transférées demande simple. Il vous permet, entre autres, d'indiquer la progression de l'importation pour les anciens navigateurs. qui ne sont pas compatibles par défaut avec la progression de l'importation.
Reprendre une importation interrompue
Si une demande d'importation est interrompue avant de recevoir une réponse ou si vous recevez une
HTTP 503 Service Unavailable
du serveur, vous devez alors reprendre l'importation interrompue. Pour ce faire :
- Interrogez l'état. Interrogez l'état actuel de l'importation en envoyant une requête à l'URI d'importation.
avec
X-Goog-Upload-Command
défini surquery
.Remarque : Vous pouvez interroger l'état entre les fragments, et pas seulement si l'importation est interrompue. C'est Cela peut être utile, par exemple, si vous souhaitez afficher les indications de progression de l'importation pour les anciens navigateurs.
- Obtenez le nombre d'octets importés. Traitez la réponse à partir de la requête d'état. Le serveur utilise
l'en-tête
X-Goog-Upload-Size-Received
dans sa réponse pour spécifier le nombre d'octets reçus jusqu'à présent. - Importez les données restantes. Enfin, maintenant que vous savez où reprendre la requête, envoyez le
les données restantes
ou le fragment actuel. Notez que vous devez traiter les données restantes comme un fragment séparé dans les deux cas, donc
vous devez définir l'en-tête
X-Goog-Upload-Offset
avec le décalage approprié lorsque vous reprenez l'importation.
Exemple : Reprendre une importation interrompue
1) Interrogez l'état de l'importation.
POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1 Host: androidovertheair.googleapis.com X-Goog-Upload-Command: query
Comme pour toutes les commandes, le client doit vérifier l'en-tête X-Goog-Upload-Status
dans la réponse HTTP d'une commande de requête.
Si l'en-tête est présent et que la valeur n'est pas active
, cela signifie que l'importation a déjà été arrêtée.
2) Procédez à l'extraction du nombre d'octets importés jusqu'à présent à partir de la réponse.
La réponse du serveur utilise l'en-tête X-Goog-Upload-Size-Received
pour indiquer qu'il a
reçu les 43 premiers octets
du fichier jusqu’à présent.
HTTP/1.1 200 OK X-Goog-Upload-Status: active X-Goog-Upload-Size-Received: 42
3) Reprenez l'importation là où elle s'était arrêtée.
La requête suivante reprend l'importation en envoyant les octets restants du fichier, en commençant par l'octet 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
Bonnes pratiques
En ce qui concerne l'importation de médias, il est utile de connaître certaines bonnes pratiques en matière de traitement des erreurs.
- Reprenez ou relancez les importations qui échouent en raison d'interruptions de connexion ou d'erreurs
5xx
, parmi lesquelles :500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Si une erreur de serveur
5xx
est renvoyée lors de la reprise ou de la nouvelle tentative d'importation, utilisez une stratégie d'intervalle exponentiel entre les tentatives. Ces erreurs peuvent se produire quand un serveur est surchargé. L'intervalle exponentiel entre les tentatives peut aider à résoudre ce type de problème lors des pics de volumes de requêtes ou de trafic réseau. - Les autres types de requêtes ne doivent pas être gérés par un intervalle exponentiel entre les tentatives, mais vous pouvez toujours en relancer un certain nombre. Lorsque vous relancez ces requêtes, limitez le nombre de tentatives. Par exemple, votre code peut limiter à 10 tentatives ou moins avant de signaler une erreur.
- Traitez les erreurs
404 Not Found
lorsque vous effectuez des importations avec reprise en recommençant l'importation depuis le début.
Intervalle exponentiel entre les tentatives
L'intervalle exponentiel entre les tentatives est une stratégie standard en matière de traitement d'erreurs pour les applications réseau, selon laquelle le client relance périodiquement une requête ayant échoué sur une durée de plus en plus longue. Si un volume élevé de requêtes ou un trafic réseau important provoquent des erreurs sur le serveur, l'intervalle exponentiel entre les tentatives peut s'imposer comme une stratégie efficace pour traiter ces erreurs. À l'inverse, cette stratégie n'est pas pertinente pour traiter les erreurs sans rapport avec le volume réseau ou les temps de réponse, telles que les erreurs associées aux identifiants d'autorisation non valides ou aux fichiers introuvables.
Utilisé correctement, l'intervalle exponentiel entre les tentatives augmente l'efficacité de l'utilisation de la bande passante, réduit le nombre de requêtes nécessaires pour obtenir une réponse positive et optimise le débit des requêtes dans les environnements avec simultanéité.
Le fonctionnement de l'intervalle exponentiel simple entre les tentatives se présente comme suit :
- Vous envoyez une requête à l'API.
- Vous recevez une réponse
HTTP 503
, qui indique que vous devez relancer la requête. - Vous patientez 1 seconde + "random_number_milliseconds", puis vous relancez la requête.
- Vous recevez une réponse
HTTP 503
, qui indique que vous devez relancer la requête. - Vous patientez 2 secondes + "random_number_milliseconds", puis vous relancez la requête.
- Vous recevez une réponse
HTTP 503
, qui indique que vous devez relancer la requête. - Vous patientez 4 secondes + "random_number_milliseconds", puis vous relancez la requête.
- Vous recevez une réponse
HTTP 503
, qui indique que vous devez relancer la requête. - Vous patientez 8 secondes + "random_number_milliseconds", puis vous relancez la requête.
- Vous recevez une réponse
HTTP 503
, qui indique que vous devez relancer la requête. - Vous patientez 16 secondes + "random_number_milliseconds", puis vous relancez la requête.
- Vous arrêtez, puis vous signalez ou consignez une erreur.
Dans le flux ci-dessus, "random_number_milliseconds" correspond à un nombre aléatoire de millisecondes inférieur ou égal à 1 000. Cette étape est nécessaire, car l'introduction d'un petit délai aléatoire permet de répartir la charge de manière plus uniforme et d'éviter l'embase du serveur. La valeur de "random_number_milliseconds" doit être redéfinie après chaque temps d'attente.
Remarque : L'attente correspond toujours à (2 ^ n) + "random_number_milliseconds", où "n" est un entier augmentant de manière monotone défini initialement sur 0. L'entier "n" est augmenté de 1 pour chaque itération (chaque requête).
L'algorithme est configuré pour se terminer lorsque "n" vaut 5. Ce plafond empêche les clients d'effectuer des relances indéfiniment et entraîne un délai total d'environ 32 secondes avant qu'une requête ne soit considérée comme une "erreur non récupérable". Vous pouvez tout à fait définir un nombre maximal de tentatives plus élevé, surtout si une longue importation est en cours d'exécution. Veillez simplement à limiter le délai des nouvelles tentatives de manière raisonnable, par exemple à moins d'une minute.