Dans un an…

"Face au monde qui change, il vaut mieux penser le changement que changer le pansement." Pierre Dac
  • Home
  • A Propos
26 Jan 2010

Android : uploader une image sur un serveur web

Une petite Mise à jour : pour écrire l’image pour envoi : utilisation de Bitmap.compress !
Ultra plus rapide !!!!

Un petit tuto pour apprendre à uploader une image (jpg ou autre) depuis votre application android vers un serveur web.
Pour ce genre de tâche qui peut être longue, Android conseille d’implémenter un Service plutôt qu’une activité : un service tourne en tâche de fond et ne bloque pas l’application.

Pour ce tuto :

  • créez une nouvelle application TutoUpload et une classe TutoUpload.
  • créez ensuite une deuxième classe HttpUploader
  • n’oubliez pas de déclarer ces classes dans le Manifest et d’ajouter la permission internet pour l’application
  • créez le fichier main.xml pour la layout de la classe TutoUpload

Le code de la classe TutoUpload :

package com.test.upload;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class TutoUpload extends Activity {

	protected Uri image=null; //acces au fichier via contentResolver
	File fichier; //le fichier à uploader

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //un bouton pour envoi du fichier vers le serveur
        final Button validbutton = (Button) findViewById(R.id.send);
		validbutton.setOnClickListener(send_listener);
    }

	//pour valider tout pour envoi vers site web
	OnClickListener send_listener = new OnClickListener() {
		public void onClick(View v) {

			image = Uri.fromFile(fichier);
			Intent uploadIntent = new Intent( );
			uploadIntent.setClassName("com.test.upload", "com.test.upload.HttpUploader");
			uploadIntent.setData(image);
			startService(uploadIntent);
		}
	};

	@Override
	protected void onPause() {
		super.onPause();
	}

	@Override
	protected void onStop() {
		Log.i(getClass().getSimpleName(),"on stop");
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
}

Le code du service HttpUploader

package com.test.upload;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.provider.MediaStore;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class HttpUploader extends Service {

	private Intent mInvokeIntent;
	private volatile Looper mUploadLooper;
	private volatile ServiceHandler mUploadHandler;

	private int check = 0;

	private final class ServiceHandler extends Handler {
		public ServiceHandler(Looper looper) {
			super(looper);
		}

		@Override
		public void handleMessage(Message msg) {
			//get extra datas
			Uri selectedImg = (Uri)msg.obj;
			Log.i(getClass().getSimpleName(),"selectedImg =" + selectedImg);

			//upload the file to the web server
			doHttpUpload(selectedImg);

			Log.i(getClass().getSimpleName(), "Message: " + msg);
			Log.i(getClass().getSimpleName(), "Done with #" + msg.arg1);
			stopSelf(msg.arg1);
		}
	};

	// Method called when (an instance of) the Service is created
	public void onCreate() {
		Log.i(getClass().getSimpleName(),"HttpUploader on create");

		// This is who should be launched if the user selects our persistent
		// notification.
		mInvokeIntent = new Intent();
		mInvokeIntent.setClassName("com.test.upload", "com.test.upload.HttpUploader");

		// Start up the thread running the service.  Note that we create a
		// separate thread because the service normally runs in the process's
		// main thread, which we don't want to block.
		HandlerThread thread = new HandlerThread("HttpUploader");
		thread.start();

		mUploadLooper = thread.getLooper();
		mUploadHandler = new ServiceHandler(mUploadLooper);
	}

	public void onStart(Intent uploadintent, int startId) {
		// recup des data pour envoi via msg dans la msgqueue pour traitement
		Message msg = mUploadHandler.obtainMessage();
		msg.arg1 = startId;
		//on place l'uri reçu dans l'intent dans le msg pour le handler
		msg.obj = uploadintent.getData();
		mUploadHandler.sendMessage(msg);
		Log.d(getClass().getSimpleName(), "Sending: " + msg);

	}

	public void doHttpUpload(Uri myImage) {
		String lineEnd = "\r\n";
		String twoHyphens = "--";
		String boundary = "*****";
		String photofile = null;
		String httpResponse; //to read http response
		String filename=null;

	        String urlString = "http://www.site.com/fileUpload.php";
		HttpURLConnection conn = null;

		InputStream fis = null;
		Bitmap mBitmap=null;
		String pathfile;

		if (myImage != null) {
			//on récupère le nom du fichier photo construit avec date et heure
			filename = "photo.jpg";

			String[] projection = { MediaStore.Images.ImageColumns.DATA, MediaStore.Images.ImageColumns.DISPLAY_NAME};
			ContentResolver cr = getContentResolver();
			Cursor c = cr.query(myImage, projection, null, null, null);
			if (c!=null && c.moveToFirst()) {
				pathfile = c.getString(0); //column0Value
				photofile = c.getString(1);     //column1Value
				Log.i(getClass().getSimpleName(),"Data : " +pathfile);
				Log.i(getClass().getSimpleName(),"Display name : " + photofile);
			}

			try {
				fis = getContentResolver().openInputStream(myImage);
				mBitmap = BitmapFactory.decodeStream(fis);

				try {
					int bytesAvailable = fis.available();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Log.i(getClass().getSimpleName(),"échec de lecture de la photo");
					stopSelf();
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				Toast.makeText(HttpUploader.this, "échec de lecture de la photo ", Toast.LENGTH_SHORT).show();
				Log.i(getClass().getSimpleName(),"échec de lecture de la photo");
				stopSelf();
			} 

		} else Log.i(getClass().getSimpleName(),"myImage is null");

		try {
			URL site = new URL(urlString);
			conn = (HttpURLConnection) site.openConnection();

			//on peut écrire et lire
			conn.setDoOutput(true);
			conn.setDoInput(true);

			// Use a post method.
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);

			DataOutputStream dos = new DataOutputStream( conn.getOutputStream() );

			dos.writeBytes(twoHyphens + boundary + lineEnd);
			Log.i(getClass().getSimpleName(),"Display name : " + photofile);
			Log.i(getClass().getSimpleName(),"Filename : " + filename);
			dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + filename + "\"" + lineEnd);
			dos.writeBytes(lineEnd);

			Log.i(getClass().getSimpleName(),"Headers are written");

                       //compression de image pour envoi
			mBitmap.compress(CompressFormat.JPEG, 75, dos);

			// send multipart form data necesssary after file data...
			dos.writeBytes(lineEnd);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

			// close streams
			fis.close();
			dos.flush();
			dos.close();
			Log.e("fileUpload","File is written on the queue");

		} catch (MalformedURLException e) {
			e.printStackTrace();
			Toast.makeText(HttpUploader.this, "échec de connexion au site web ", Toast.LENGTH_SHORT).show();
			Log.i(getClass().getSimpleName(),"échec de connexion au site web 1");
		} catch (IOException e) {
			e.printStackTrace();
			Toast.makeText(HttpUploader.this, "échec de connexion au site web ", Toast.LENGTH_SHORT).show();
			Log.i(getClass().getSimpleName(),"échec de connexion au site web 2");
		} 

		//lecture de la réponse http
		try {
			BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			Log.i(getClass().getSimpleName(),"try HTTP reponse");
			while ((httpResponse = rd.readLine()) != null) {
				Log.i(getClass().getSimpleName(),"HTTP reponse= " + httpResponse);
				if(httpResponse.contains("error")) {
					//there is a http error
					check += 1;
				}
			}
			rd.close();
		} catch (IOException ioex){
			Log.e("HttpUploader", "error: " + ioex.getMessage(), ioex);
			ioex.printStackTrace();
			Toast.makeText(HttpUploader.this, "échec de lecture de la réponse du site web ", Toast.LENGTH_SHORT).show();
			Log.i(getClass().getSimpleName(),"échec de lecture de la réponse du site web");
		}

	}

	// Method called when the (instance of) the Service is requested to terminate
	public void onDestroy() {
		mUploadLooper.quit();

		if(check == 0) { //http response contains no error
			Toast.makeText(HttpUploader.this, "photo envoyée", Toast.LENGTH_SHORT).show();
		} else {
			Toast.makeText(HttpUploader.this, "échec d'envoi de la photo", Toast.LENGTH_SHORT).show();
		}
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
}

Le fichier de layout main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />

    <Button
   		android:id="@+id/send"
   		android:layout_width="wrap_content"
   		android:layout_height="wrap_content"
   		android:layout_marginTop="10px"
 		android:text="Envoi" />
</LinearLayout>

A vous de jouer !

26 January, 2010 at 17:15 by flo

Tags: android, tutoriel, upload fichier serveur
Posted in android | 5 Comments »

25 Jan 2010

Une mise à jour de l’appli Ptit Coin

Une mise à jour de l’appli P’tit Coin est disponible sur Android Market.
J’ai réduis la taille des photos prises depuis l’application pour que l’envoi soit plus rapide.

25 January, 2010 at 17:04 by flo

Posted in android | No Comments »

24 Jan 2010

Twitter Weekly Updates for 2010-01-24

  • RT @Korben: "Le petit bonhomme en mousseuuuuu…" lalalalalallaa : pas merci : toute la matinée dans la tête ;o) arhhhhhhhhhhhhhhh #
  • de retour de la nuit sans web…… ouf ! bien 45 min sans DNS pour nous quand même ! #
  • RT @mrboo: C'est toujours bon de le rappeler : http://bit.ly/7rhoOh #
  • et hop la première appli android made in chez nous nous se trouve sur le market….. : http://bit.ly/4xbtGe #
  • une suggestion de bon plugin wordpress pour insérer du code source dans un post ??? #
  • c'est sympa : http://bit.ly/4s6O7I et c'est Yrgane qui le fait : http://bit.ly/7gYH7f #
  • @Alkanz oui sanitaire est le bon mot ! ça pousse à la réflexion ! vulgaire non, c'est le style larcenet…. in reply to Alkanz #
  • RT @AymericJ: En train de relire avec un certain plaisir cette perle de Larcenet : http://bit.ly/79Ebji : troublant de vérité ! #
  • RT @dauran: Aider une association bien implantée au cœur même d'Haïti http://bit.ly/5IPMrk à RT svp #
  • RT @romm1: La stratégie d'Archos face à Apple : le rôle clé d'Androïd http://bit.ly/6j3UPX #
  • @AymericJ : tweetDeck….. in reply to AymericJ #
  • android market : 25$ à payer pour avoir le droit de publier une application ??????? #
  • RT @mlerouzic: Ah ! ;-) => La France et l'Allemagne déconseillent l'utilisation d'Internet Explorer http://bit.ly/5rLaZt : enfin !!! #
  • RT @kreestal: Si vous cherchez une mini machine à donuts, c'est par ici: http://bit.ly/8p91n4 -_-; : j'en veux une !!! #

Powered by Twitter Tools

24 January, 2010 at 19:00 by flo

Posted in Récréation | No Comments »

24 Jan 2010

Un peu de sagesse zen.

L’auteur du blog feuille de chou donne sa liste de livres zen. Je n’en ai leu aucun mais la seule citation du livre Les quatre accords toltèques, de Miguel Ruiz me plait beaucoup :

Quatre principes de vie issus de la sagesse amérindienne. Quatre phrases simples qui changent la vie, mais pas si faciles que cela à mettre en pratique:

- Que votre parole soit impeccable;

- Ne réagissez à rien de façon personnelle;

- Ne faites aucune supposition;

- Faites toujours de votre mieux.

Ces 4 principes devraient être appliqués par tous (moi la première) lors de nos digressions sur le web…..

A méditer donc … euh, non, à appliquer ;o)

24 January, 2010 at 16:08 by flo

Posted in Récréation | No Comments »

19 Jan 2010

L’appli P’tit Coin…

Et voilà après tout ce boulot, le plaisir de publier ! Une application android pour téléphone android !

L’appli P’tit Coin est disponible sur Android Market dans la catégorie voyage, elle est GRATUITE.
J’ai mis à jour la fiche sur Androlib.

Une description rapide : cette application permet de trouver les toilettes publiques autour de vous.
L’idée c’est que tout le monde peut ajouter des toilettes pour grossir la base de données.

Les plus :

  • vous pouvez paramétrer la distance de recherche : quand on est à pied, une distance de 1 km c’est bien, en voiture, 10 ou 20 km c’est mieux,
  • vous pouvez associer une photo prise avec votre téléphone avec les P’tit Coin que vous ajoutez,
  • vous pouvez créer un compte sur le site web associé à l’appli : www.ptitcoin.com
  • si vous avez un compte sur le site web associé, vous pouvez enregistrer votre mot de passe et votre login dans l’application pour retrouver ensuite sur internet les P’tits Coin que vous avez ajoutés.

A chaque P’tit Coin entré, il y a au moins un commentaire / nom ou adresse associé. Vous pouvez ensuite en plus mettre une note (de 1 à 4) au P’tit Coin que vous ajoutez.

19 January, 2010 at 22:59 by flo

Tags: p'tits coins, toilettes publiques, wc publiques
Posted in android | 5 Comments »

19 Jan 2010

Android WebView

ou comment ouvrir un navigateur web depuis une appli….

Je rédige ce petit tutoriel car l’exemple qui se trouve sur le site web d’android ne fonctionne pas. Le voici donc revu et corrigé !

L’objet WebView vous permet de créer votre propre Activity pour un browser internet.
Ca peut être l’activité principale de votre application ou elle peut être lancée via un intent.

Pour tester, créer un nouveau projet OnTheWeb avec comme activity : OnTheWeb et comme nom de package : com.test.ontheweb.

Voici le code de l’activité :

package com.test.ontheweb;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class OnTheWeb extends Activity {
	WebView webview;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mywebview);

		webview = (WebView)findViewById(R.id.webview);
		webview.setWebViewClient(new myWebViewClient());
		webview.getSettings().setJavaScriptEnabled(true);
		webview.loadUrl("http://www.dansunan.com");
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
			webview.goBack();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	private class myWebViewClient extends WebViewClient {
		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			view.loadUrl(url);
			return true;
		}
	}
}

Et le fichier mywebview.xml qui va bien :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

</LinearLayout>

Bien sûr , pour avoir accès à internet, il faut ajouter à votre fichier AndroidManifest.xml la ligne :

<uses-permission android:name=”android.permission.INTERNET” />

NB : l’erreur du tutoriel original se trouve dans le fichier .xml qui décrit la WebView.
La LinearLayout définie doit avoir les propriétés :

android:layout_width=”fill_parent”
android:layout_height=”fill_parent”

au lieu de :

android:layout_width=”wrap_content”
android:layout_height=”wrap_content”

19 January, 2010 at 14:27 by flo

Tags: android, tutoriel, webview
Posted in android | No Comments »

18 Jan 2010

Du changement….

Comme vous ne le savez peut être pas je travaille avec ce cher Dauran dans une entreprise (la notre) du même nom.

Du coup dauran.com c’est un peu le nom de domaine de notre boulot.

Du coup www.dansunan.com reste le blog Dans un an… mais se trouve à l’adresse http://flo.dauran.com.

Du coup je vous invite à continuer à me suivre, les 2 adresses fonctionnent toujours, vive le redirect php !

Du coup je vais essayer de faire évoluer ce blog vers plus de technique….. Mon dada en ce moment c’est Android avec du développement d’application et de site web associé….

A suivre…….

18 January, 2010 at 15:09 by flo

Tags: dansunan, dauran
Posted in Récréation | No Comments »

17 Jan 2010

Twitter Weekly Updates for 2010-01-17

  • RT @ElianChrebor: Amazing Wild Life photo gallery by Nicj Brandt http://bit.ly/5WU1Yv #photo #animals #wildlife (via @mrboo) #
  • RT @Vinvin: ;-) RT @mediamaispasque: Besson a suspendu les expulsions vers Haïti, il est cool ce mec finalement ;o) #
  • @donkey20 : une spéciale dédicace…… http://twitpic.com/xo440 #

Powered by Twitter Tools

17 January, 2010 at 19:00 by flo

Posted in Récréation | No Comments »

10 Jan 2010

Twitter Weekly Updates for 2010-01-10

  • @donkey20 : tu les bichonnes les petits ;o) in reply to donkey20 #
  • j'adore parler toute seule quand mon voisin de bureau à son casque sur les oreilles ;o) #
  • Nexus One : un concurrent de poids à l'iPhone c'est bien, un outil de monopole de plus pour google sur les pubs = pas top => avis partagé #
  • hey de retour sur twitter ! peut être un peu tard : bonne année 2010 ;o) original non !? #
  • RT @ThibautNinove: Voilà une des raisons pour lesquelles je ne risque pas de troquer mon iPhone contre un Nexus One http://tnv.li/aqD6X #

Powered by Twitter Tools

10 January, 2010 at 19:00 by flo

Posted in Récréation | No Comments »

27 Dec 2009

Twitter Weekly Updates for 2009-12-27

  • Les petits lutins ont fait leur travail hier soir : emballage des cadeaux terminé….. #

Powered by Twitter Tools

27 December, 2009 at 19:00 by flo

Posted in Récréation | No Comments »

« Older Entries
Newer Entries »
  • Appli Android

    L'appli P'tit Coin

    1er mars 2010 : L'appli P'tit Coin v3.0

    5 février 2010 : Nouvelle Version de l'appli P'tit Coin

    25 janvier 2010 : Mise à jour de l'appli P'tit Coin

  •  

    March 2010
    M T W T F S S
    « Feb    
    1234567
    891011121314
    15161718192021
    22232425262728
    293031  
  • Recent Posts

    • Twitter Weekly Updates for 2010-03-07
    • Suivre l’utilisation de son appli Android avec Google Analytics
    • P’tit Coin v3.0
    • Twitter Weekly Updates for 2010-02-21
    • Twitter Weekly Updates for 2010-02-14
  • Categories

    • android
    • Audience
    • Business
    • e-commerce
    • eco-reflexion
    • écolo ? non intelligent !
    • education
    • livre
    • media
    • Récréation
    • société
    • spectacle enfant
    • Uncategorized
  • Blogroll

    • Dauran
    • Forex
    • L’art en couleurs
    • P'tit Coin
Dans un an… is proudly powered by WordPress
Design & code by Jonk
Entries (RSS) and Comments (RSS).