Création de l’activité «BlobsActivity»








télécharger 140.7 Kb.
titreCréation de l’activité «BlobsActivity»
date de publication24.12.2016
taille140.7 Kb.
typeDocumentos
Windows Azure Toolkit For Devices

3/ Gestion des Blobs sous Android

Dans Windows Azure, les Blobs sont en quelque sorte des fichiers qui peuvent être volumineux si nécessaire. Les Blobs sont regroupés dans des Blob Container qui ne possèdent qu’un seul niveau hiérarchique (la racine). Tous les blobs sont stockés sous cette racine, les uns à la suite des autres. Il est possible de simuler une pseudo hiérarchie en incluant dans le nom des blobs des « / ».

Donc si je résume, pour stocker ou récupérer le contenu d’un blob (d’un fichier) j’ai besoin de fournir le nom du blob container qui le contient, ainsi que le nom du blob lui-même.

Pour illustrer le fonctionnement des blobs nous allons repartir du code utilisé pour l’authentification ASP Membership et l’agrémenter d’une page de gestion de blobs.

Accès sécurisé


Pour être en mesure d’accéder aux blobs il faut mémoriser quelque part le token qui est retourné par la fonction d’authentification. Dans la partie consacrée à l’authentification ASP Membership, nous avions stocké le token d’identification dans une variable static de la classe « Global ». Ce token est stocké sous la forme d’un objet de type « WAZServiceAccount ».

Pour mettre en pratique la gestion des blobs, nous allons stocker une photo (prise avec l’appareil photo du device Android) et la stocker dans Windows Azure. Nous listerons aussi tous les blobs présents dans le blob container qui nous servira à stocker nos photos. En avant !

Création de l’activité « BlobsActivity »


Vous allez créer une nouvelle activité qui se compose d’une liste « LvBlobs », d’un bouton « BouPhoto », d’une image « IvBlob » et d’une progress bar « progressBar ».

La liste permettra d’afficher tous les blobs présents dans le blob container, le bouton à prendre une photo pour l’uploader dans Windows Azure, l’image à afficher le contenu d’un blob sélectionné dans la liste.

Votre page devrait avoir en gros l’aspect suivant :



Avant d’oublier, nous allons tout de suite ajouter le code de navigation vers cette nouvelle activité en réponse au clic sur le bouton « Blobs » depuis l’activité « MenuActivity» :

@Override

public void onClick(View v)

{

if (v == bouBlobs)

{

Intent wIntent = new Intent(this, BlobsActivity.class);

startActivity(wIntent);

}

else if (v == bouQueues)

{

}

else if (v == bouTables)

{

}

}

Lister le contenu d’un blob container


Dans cet exemple nous allons utiliser un blob container dont le nom est « photos3 ». Chaque photo stockée dans ce container aura comme nom la date du jour (ex 20120510163044.jpg pour une image prise le 10/05/2012 à 16h30 et 44 secondes).

Pour travailler sur les blobs il nous faut un objet spécialisé possédant les credentials de l’utilisateur connecté. Cet objet, de type « CloudBlobClient » est créé à partir des informations d’authentification en utilisant la fonction « createCloudBlobClient » du compte utilisateur  que nous avons précédemment stocké dans la classe « Global ».

Nous allons stocker cet objet au niveau des variables globales de l’activité « BlobsActivity » pour le réutiliser sans avoir à le résoudre à chaque fois :

if (blobClient == null)

{

blobClient = Global.account.createCloudBlobClient();

}

Une fois que l’on possède un client de gestion des blobs, il nous faut une référence vers le blob container que l’on veut lister. Il suffit d’utiliser la fonction « getContainerReference » du client de gestion des blobs avec en paramètre le nom du container :

CloudBlobContainer wContainer = blobClient.getContainerReference("photos3");

Maintenant que nous avons une référence vers le container qui nous intéresse, il suffit de lister son contenu. Mais avant de faire cela, il est vivement conseillé de le créer (si besoin uniquement) pour éviter des erreurs liées au fait qu’il n’existe pas. C’est la méthode « createIfNotExists » du container qu’il faut utiliser :

if (wContainer.createIfNotExist())

{

// On liste les blobs présents dans ce container

}

Pour lister le contenu du blob container, il suffit de parcourir la collection des blobs retournée par la fonction « listBlobs » du container. Cette fonction prend en paramètre le préfix des blobs à remonter (c’est une manière de filtrer les résultats et ainsi optimiser le temps de réponse) et un booléen stipulant si l’on souhaite une version « plate » ou « hiérarchique » des informations (voir la documentation de Windows Azure pour mieux comprendre la différence entre les deux manières de remonter les informations). Nous allons utiliser une vue « plate » car nous n’avons dans cet exemple aucune notion de hiérarchie dans notre blob container :

for (CloudBlob wBlob : wContainer.listBlobs("", true))

{

// Ajouter ici chaque blob remonté dans une collection privée pour affichage

}

Voilà, l’enchainement des actions à réaliser pour lister le contenu d’un blob container est aussi simple que ça !

Comme pour les fonctions d’authentification, nous allons utiliser les services d’une AsyncTask pour effectuer les opérations de manière asynchrones.

Pendant l’opération le bouton de prise de photos et la liste des blobs sont désactivés, l’image est cachée et la progress bar est affichée pour faire patienter l’utilisateur. En cas de problème, un message d’erreur est affiché avec la raison du problème rencontré.

Un adapter a été créé pour lister les noms des blobs retournés. Cet adapter est « nourri » avec les noms de blobs au fur et à mesure de leur itération.

L’architecture de cette AsyncTask est très classique. En voici le code complet :

private class ListerBlobsTask extends AsyncTask

{

private Exception _exception = null;

@Override

protected Void doInBackground(Void... params)

{

try

{

// On récupère le blob client si on ne l'a pas déjà

if (blobClient == null)

{

blobClient = Global.account.createCloudBlobClient();

}

// On crée la référence vers le container que l'on veut lister

CloudBlobContainer wContainer = blobClient.getContainerReference("photos3");

if (wContainer.createIfNotExist())

{

// On liste les blobs présents dans ce container

for (CloudBlob wBlob : wContainer.listBlobs("", true))

{

blobsAdapter.blobs.add(wBlob.getName());

}

}

}

catch (Exception ex)

{

_exception = ex;

}

return null;

}

protected void onPostExecute(Void result)

{

progressBar.setVisibility(View.GONE);

if (this._exception != null)

{

Global.ShowMessage(BlobsActivity.this,

"Une erreur s'est produite !",

this._exception.getMessage());

}

else

{

blobsAdapter.notifyDataSetChanged();

bouPhoto.setEnabled(true);

lvBlobs.setEnabled(true);

}

}

}

Voici le code de l’adapter utilisé pour afficher les blobs :

private class BlobsAdapter extends BaseAdapter

{

private LayoutInflater layoutInflater;

public ArrayList blobs;

public BlobsAdapter(Context wContext)

{

blobs = new ArrayList();

layoutInflater = LayoutInflater.from(wContext);

}

@Override

int getCount()

{

if (blobs == null)

{

return 0;

}

else

{

return blobs.size();

}

}

@Override

public Object getItem(int position)

{

return blobs.get(position);

}

@Override

public long getItemId(int position)

{

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent)

{

if (convertView == null)

{

convertView = layoutInflater.inflate(R.layout.blobitem, null);

}

TextView txtBlobName = (TextView)convertView.findViewById(R.id.txtBlobName);

txtBlobName.setText(blobs.get(position));

return convertView;

}

}

Et enfin, l’appel à la tâche permettant de lister les blobs présents dans le container. Cet appel est lancé directement depuis la méthode « onCreate » de l’activité :

ListerBlobsTask wTask = new ListerBlobsTask();

wTask.execute();


Prendre une photo et la stocker dans Windows Azure


En soit, prendre une photo n’est pas très compliqué. Il suffit de demander au système de s’en occuper en lançant une intent adaptée. La photo sera stockée dans le fichier « capture.jpg » sur la carte mémoire d’extension :

public static final int REQUEST_CAPTURE = 1;

@Override

public void onClick(View v)

{

if (v == bouPhoto)

{

ivBlob.setVisibility(View.GONE);

Intent wIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

File wFile = new File(Environment.getExternalStorageDirectory(), "capture.jpg");

Uri wOutputFileUri = Uri.fromFile(wFile);

wIntent.putExtra(MediaStore.EXTRA_OUTPUT, wOutputFileUri);

startActivityForResult(wIntent, BlobsActivity.REQUEST_CAPTURE);

}

}

Au retour de l’activité de capture, on peut lancer la tâche qui sera chargée du stockage de l’image dans Windows Azure :

@Override

public void onActivityResult(int requestCode, int resultCode, Intent data)

{

if (requestCode == REQUEST_CAPTURE)

{

// Réponse de l'activité de capture caméra

// resultCode = RESULT_OK -> La capture de se trouve dans le fichier capture.jpg

if (resultCode == RESULT_OK)

{

// On compose le nom de l'image source

String wFilename = Environment.getExternalStorageDirectory() + "/capture.jpg";

// On affiche la progress bar

bouPhoto.setEnabled(false);

lvBlobs.setEnabled(false);

progressBar.setVisibility(View.VISIBLE);

// On lance la tâche d'ajout de l'image au container

UploadBlobTask wTask = new UploadBlobTask();

wTask.execute(wFilename);

}

}

}

Reste maintenant à définir la tâche de stockage, qui sera, comme d’habitude dérivée de la classe AsyncTask.

Pour stocker un nouveau blob il faut quatre éléments :

  1. Un client de gestion des blob (on connaît déjà)

  2. Une référence vers le blob container (on connaît aussi)

  3. Un nom de blob

  4. Une source de données (ici les octets composant l’image)

On récupère une référence vers le blob container :

CloudBlobContainer wContainer = blobClient.getContainerReference("photos3");

Nous allons donner à nos images un nom basé sur la date et l’heure du moment :

Calendar c = Calendar.getInstance();

SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

String wName = df.format(c.getTime()).concat(".jpg");

Et créer maintenant une référence vers le blob à créer dans le blob container. La référence est gérée par un objet de type « CloudBlockBlob » :

CloudBlockBlob wBlob = wContainer.getBlockBlobReference(wName);

Nous avons tout maintenant pour récupérer le train d’octets de l’image et l’uploader vers Windows Azure :

// wImageName contient le chemin vers le fichier image à utiliser

Bitmap bitmap = BitmapFactory.decodeFile(wImageName);

OutputStream stream = wBlob.openOutputStream();

bitmap.compress(CompressFormat.JPEG, 75, stream);

stream.close();

On peut aussi associer au blob des métadonnées :

wBlob.getProperties().contentType = "image/jpeg";

wBlob.uploadProperties();

Avant d’uploader les données, il est recommandé de vérifier que le blob container existe (comme nous l’avons déjà fait au moment de lister son contenu).

Comme vous pouvez le constater, rien de très compliqué à faire.

Voici le code complet de cette nouvelle AsyncTask :

private class UploadBlobTask extends AsyncTask

{

private Exception _exception = null;

@Override

protected Void doInBackground(String... params)

{

// On récupère le nom de l'image à uploader

String wImageName = params[0];

try

{

// On crée la référence vers le container que l'on veut utiliser

CloudBlobContainer wContainer = blobClient.getContainerReference("photos3");

if (wContainer.createIfNotExist())

{

Calendar c = Calendar.getInstance();

SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

String wName = df.format(c.getTime()).concat(".jpg");

CloudBlockBlob wBlob = wContainer.getBlockBlobReference(wName);

Bitmap bitmap = BitmapFactory.decodeFile(wImageName);

OutputStream stream = wBlob.openOutputStream();

bitmap.compress(CompressFormat.JPEG, 75, stream);

stream.close();

wBlob.getProperties().contentType = "image/jpeg";

wBlob.uploadProperties();

blobsAdapter.blobs.add(wName);

}

}

catch (Exception ex)

{

_exception = ex;

}

return null;

}

protected void onPostExecute(Void result)

{

progressBar.setVisibility(View.GONE);

bouPhoto.setEnabled(true);

lvBlobs.setEnabled(true);

if (this._exception != null)

{

Global.ShowMessage(BlobsActivity.this,

"Une erreur s'est produite !",

this._exception.getMessage());

}

else

{

blobsAdapter.notifyDataSetChanged();

}

}

}


Récupérer le contenu d’un blob et l’afficher


Vous vous en doutez bien, pour récupérer le contenu d’un blob il nous faut les mêmes informations que pour le créer :

  1. Un client de gestion des blob

  2. Une référence vers le blob container

  3. Le nom du blob à récupérer

Il faut utiliser la méthode « download » de la classe « CloudBlockBlob » pour récupérer les données (train d’octets) du blob.

Je vous donne directement le code de l’AsyncTask correspondante car maintenant vous être habitué à ce type de classe :

private class DownloadBlobTask extends AsyncTask

{

private Exception _exception = null;

private Bitmap _bitmap = null;

@Override

protected Void doInBackground(String... params)

{

try

{

// On récupère le nom du blob passé en paramètres

String wBlobName = params[0];

// On récupère le blob client si on ne l'a pas déjà

if (blobClient == null)

{

blobClient = Global.account.createCloudBlobClient();

}

// On crée la référence vers le container qui stocke le blob

CloudBlobContainer wContainer = blobClient.getContainerReference("photos3");

// On crée la référence vers le blob à télécharger

CloudBlockBlob wBlockBlob = wContainer.getBlockBlobReference(wBlobName);

// On télécharge son contenu

ByteArrayOutputStream wOutputStream = new ByteArrayOutputStream();

wBlockBlob.download(wOutputStream);

byte[] wContent = wOutputStream.toByteArray();

// On l'affiche

ByteArrayInputStream wInputStream = new ByteArrayInputStream(wContent);

_bitmap = BitmapFactory.decodeStream(wInputStream);

wInputStream.close();

}

catch (Exception ex)

{

_exception = ex;

}

return null;

}

protected void onPostExecute(Void result)

{

progressBar.setVisibility(View.GONE);

if (this._exception != null)

{

Global.ShowMessage(BlobsActivity.this,

"Une erreur s'est produite !",

this._exception.getMessage());

}

else if (_bitmap != null)

{

ivBlob.setImageBitmap(_bitmap);

ivBlob.setVisibility(View.VISIBLE);

}

bouPhoto.setEnabled(true);

lvBlobs.setEnabled(true);

}

}

Dans cet exemple, on récupère le contenu d’un blob avec un appui long sur son nom dans la liste. Voici le code d’appel correspondant :

@Override

public boolean onItemLongClick(AdapterView arg0, View arg1, int arg2, long arg3)

{

// On récupère le nom du blob à afficher

String wName = blobsAdapter.blobs.get(arg2);

// On prépare l'interface

bouPhoto.setEnabled(false);

lvBlobs.setEnabled(false);

ivBlob.setVisibility(View.GONE);

progressBar.setVisibility(View.VISIBLE);

// On lance le téléchargement du blob

DownloadBlobTask wTask = new DownloadBlobTask();

wTask.execute(wName);

return true;

}

Supprimer un blob


Nous ne l’avons pas implémenté dans cet exemple mais la suppression d’un blob est une opération très simple à réaliser. Il suffit d’invoquer la méthode « delete » de la classe « CloudBlockBlob » pour réaliser l’opération. Comme toujours, il faudra réaliser cette opération dans une AsyncTask, mais ça maintenant vous en avez pris l’habitude.

Conclusion


Voilà, nous avons fait une petite visite guidée de l’utilisation des blobs avec WAT. Comme vous pouvez le constater ce n’est pas très compliqué et ça fonctionne très bien.

similaire:

Création de l’activité «BlobsActivity» iconRapport d’activite et analyse des pratiques professionnelles l’accompagnement...

Création de l’activité «BlobsActivity» iconDispositions relatives à la liberte de création et a la creation artistique
«sa communication au public,» sont insérés les mots : «notamment la mise à disposition de manière que chacun puisse y avoir accès...

Création de l’activité «BlobsActivity» iconL'art de la Renaissance en Europe
...

Création de l’activité «BlobsActivity» iconAdresse : 1 Boulevard Trimolet 21000 Dijon
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...

Création de l’activité «BlobsActivity» iconAdresse : 1 Boulevard Trimolet 21000 Dijon
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...

Création de l’activité «BlobsActivity» iconAdresse : 38 Bis Rue de l'Alma 92400 Courbevoie
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...

Création de l’activité «BlobsActivity» iconAdresse : L'Alp Arena La Blâche 05000 Gap
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...

Création de l’activité «BlobsActivity» iconAdresse : 100 Cours Charlemagne 69002 Lyon
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...

Création de l’activité «BlobsActivity» iconAdresse : 90 Chemin des Fins 74000 Annecy
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...

Création de l’activité «BlobsActivity» iconAdresse : 100 Cours Charlemagne 69002 Lyon
«Bilan pédagogique et financier» doit permettre à l’administration de retracer l’ensemble de l’activité pédagogique du dispensateur...








Tous droits réservés. Copyright © 2016
contacts
ar.21-bal.com