IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Asynctask et LocationListener : onLocationChanged jamais appelé..why ?


Sujet :

Android

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut Asynctask et LocationListener : onLocationChanged jamais appelé..why ?
    Bonjour tout l'monde =)

    Je me suis créé un programme assez simple qui affiche après appui sur un bouton les coordonnées GPS actuelles de l'apareil.
    Pour cela, j'ai donc créé une classe MainActivity avec un listener sur le bouton, et une fois celui-ci "clické" donc, il apelle une nouvelle instance de mon Asynctask qui implémente l'interface LocationListener.

    Le truc c'est que j'obtiens bien des coordonnées gps, mais ces dernières ne changent jamais (même en me déplaçant jusqu'à ma rue..Pire ! même lorsque j'éteind/rallume mon téléphone). Donc en trifouillant un peu, je me suis rendu compte que la méthode onLocationChanged n'est en fait jamais appelé dans mon programme (pas de trace dans mon LogChat..).

    Donc j'aimerais tout simplement comprendre pourquoi ^^ pourquoi elle n'est jamais appelée.
    J'ai également testé autre chose, j'ai téléchargé le projet de cette adresse qui 'à priori' devrait fonctionner hors l'application boucle en "chargement" sans jamais afficher de coordonnées... Alors je suis en train de me demander si le problème ne serait pas propre à mon appareil...

    Voici mon code, j'ai peut être oublié quelque chose dedans ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
     
    public class MainActivity extends Activity {
     
    	public static Context context;
    	public Button push = null;
    	public getGPS tache_getGPS = null;
     
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		context = getApplication().getApplicationContext();
     
    		push = (Button) findViewById(R.id.button);
    		push.setOnClickListener(new OnClickListener() {
     
    			@Override
    			public void onClick(View v) {
    				Log.i("T: onClick", "debut");
    				tache_getGPS = new getGPS();
    				tache_getGPS.execute();
    				Log.i("T: onClick", "fin");
    				// TODO Auto-generated method stub
    			}
    		});
    	}
     
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.main, menu);
    		return true;
    	}
     
    }
     
    class getGPS extends AsyncTask<Void, Integer, Location> implements
    		LocationListener {
     
    	final long REFRESH = 5 * 1000;
    	private Location location;
    	private LocationManager lm;
     
    	protected void onPreExecute() {
    		Log.i("T: onPreExcute", "debut");
    		Criteria crit = new Criteria();
    		crit.setAccuracy(Criteria.ACCURACY_FINE);
     
    		// Configure location manager - I'm using just the network provider in
    		// this example
    		lm = (LocationManager) MainActivity.context
    				.getSystemService(Context.LOCATION_SERVICE);
     
    		String best = lm.getBestProvider(crit, false);
    		Log.i("T: onPreExecute", "best : " + best);
     
    		lm.requestLocationUpdates(best, 0, 1, this);
    		location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    		// nearProgress.setVisibility(View.VISIBLE);
    		Log.i("T: onPreExcute", "fin");
    	}
     
    	protected Location doInBackground(Void... params) {
    		Log.i("T: doInBackground", "debut");
     
    		// Try to use the last known position
    		Location lastLocation = lm
    				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    		/*
    		 * // If it's too old, get a new one by location manager if
    		 * (System.currentTimeMillis() - lastLocation.getTime() > REFRESH) {
    		 * while (location == null) try { Thread.sleep(100); } catch (Exception
    		 * ex) { }
    		 * 
    		 * return location; }
    		 */
    		Log.i("T: doInBackground", "fin");
    		return lastLocation;
    	}
     
    	protected void onPostExecute(Location location) {
    		Log.i("T: onPostExecute", "debut");
    		// nearProgress.setVisibility(View.GONE);
     
    		lm = (LocationManager) MainActivity.context
    				.getSystemService(Context.LOCATION_SERVICE);
    		lm.removeUpdates(this);
     
    		Log.i("T: onPostExecute",
    				"Altitude : " + String.valueOf(location.getAltitude()));
    		Log.i("T: onPostExecute",
    				"Longitude : " + String.valueOf(location.getLongitude()));
    		Log.i("T: onPostExecute",
    				"Latitude : " + String.valueOf(location.getLatitude()));
    		Log.i("T: onPostExecute",
    				"Precision(mètre) : " + String.valueOf(location.getAccuracy()));
    		Log.i("T: onPostExecute", "fin");
     
    		Toast.makeText(
    				MainActivity.context,
    				"Altitude : " + String.valueOf(location.getAltitude()) + "\n"
    						+ "Longitude : "
    						+ String.valueOf(location.getLongitude()) + "\n"
    						+ "Latitude : "
    						+ String.valueOf(location.getLatitude()) + "\n"
    						+ "Precision(mètre) : "
    						+ String.valueOf(location.getAccuracy()),
    				Toast.LENGTH_SHORT).show();
     
    		return;
    	}
     
    	@Override
    	public void onLocationChanged(Location newLocation) {
    		Log.i("T: onLocationChanged", "debut");
    		location = newLocation;
    		Log.i("T: onLocationChanged", "fin");
    	}
     
    	@Override
    	public void onProviderDisabled(String provider) {
    		Log.i("T: onProviderDisabled", provider);
    	}
     
    	@Override
    	public void onProviderEnabled(String provider) {
    		Log.i("T: onProviderEnabled", provider);
    	}
     
    	@Override
    	public void onStatusChanged(String provider, int status, Bundle extras) {
    		Log.i("T: onStatusChanged", "provider : " + provider);
    		Log.i("T: onStatusChanged", "status : " + status);
    		Log.i("T: onStatusChanged", "extras : " + extras.toString());
    	}
     
    }
    Comme vous pouvez le voir, il y a une boucle while mis en commentaire. Si je décommente cette dernière, mon application tourne en boucle sans afficher les coordonnées gps (comportement similaire au programme que j'ai déniché sur Internet..).
    Et au cas où, voici mon manifest :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.testgps"
        android:versionCode="1"
        android:versionName="1.0" >
     
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
     
        <uses-permission android:name="android.permission.ACCESS_GPS" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.INTERNET" />
     
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.testgps.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
     
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
     
    </manifest>
    Merci d'avance pour votre aide =)

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut
    Alors petites avancées dans mon problème. J'ai refais le code sans passer par une Asynktask. Alors cette fois ci le onLocationChanged est appelé périodiquement mais ceci de façon éléatoire, je m'explique :

    Pendant un laps de temps l'icone en forme de parabole (icone gps) de mon téléphone se fixe et à partir de la onLocationChanged est appelé périodiquement toutes les 5 secondes et mes coordonnées GPS se mettent bien à jour si j'appuis plusieurs fois sur mon bouton.
    Par contre, l'icone en forme de parabole se remet ensuite a clignoter et là, le onLocationChanged n'est plus du tout appelé (sa peut durer 5minutes..) et donc lorsque j'appui sur mon boutton, les coordonnées restent toujours les mêmes..

    Dois je en déduire que mon problème vient tout simplement du fait que mon appareil n'arrive pas à communiquer "a tout les coup" avec le réseau GPS ?
    Mais ça m'étonne...il peut se passer 5/10 mn pendant que l'icone clignote alors que j'habite en plein Marseille...
    Le problème provient de mon téléphone ? ou estce que mon nouveau code présente des défaut ?
    (ça m'étonne que je n'arrive pas à attraper de manière 'fiable' de pauvres petites coordonnées gps...)

    le nouveau code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    public class MainActivity extends Activity implements LocationListener{
     
        public static Context context;
        public Button push = null;
        public getGPS tache_getGPS = null;
     
        private Location location;
        private LocationManager lm;
        final long REFRESH = 5 * 1000;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            context = getApplication().getApplicationContext();
     
            push = (Button) findViewById(R.id.button);
            push.setOnClickListener(new OnClickListener() {
     
                @Override
                public void onClick(View v) {
                    Log.i("T: onClick", "debut");
                    location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    Location lastLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (System.currentTimeMillis() - lastLocation.getTime() > REFRESH) {
                         while (location == null) 
                             try { Thread.sleep(100); } catch (Exception ex) { }
                         Log.i("FINAL : location", location.toString());
                         Toast.makeText(MainActivity.context, "location : "+location.toString(), Toast.LENGTH_SHORT).show();
                         return;
                    }
                    Log.i("FINAL : lastlocation", lastLocation.toString());
                    Toast.makeText(MainActivity.context, "lastLocation : "+lastLocation.toString(), Toast.LENGTH_SHORT).show();
                    Log.i("T: onClick", "fin");
                }
            });
        }
     
        @Override
        protected void onResume(){
            super.onResume();
            Criteria crit = new Criteria();
            crit.setAccuracy(Criteria.ACCURACY_FINE);
            lm = (LocationManager) MainActivity.context.getSystemService(Context.LOCATION_SERVICE);
     
            String best = lm.getBestProvider(crit, false);
            Log.i("T: onPreExecute", "best : " + best);
     
            lm.requestLocationUpdates(best, 1, 1, this);
        }
     
        @Override
        protected void onPause(){
            super.onPause();
            lm.removeUpdates(this);
        }
     
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
     
        @Override
        public void onLocationChanged(Location newLocation) {
            Toast.makeText(context, "onLocationChanged", Toast.LENGTH_SHORT).show();
            Log.i("T: onLocationChanged", "debut");
            location = newLocation;
            Log.i("T: onLocationChanged", "fin");
        }
     
        @Override
        public void onProviderDisabled(String provider) {
            Log.i("T: onProviderDisabled", provider);
        }
     
        @Override
        public void onProviderEnabled(String provider) {
            Log.i("T: onProviderEnabled", provider);
        }
     
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Log.i("T: onStatusChanged", "provider : " + provider);
            Log.i("T: onStatusChanged", "status : " + status);
            Log.i("T: onStatusChanged", "extras : " + extras.toString());
        }
     
    }

  3. #3
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    C'est à dire qu'en général on ne gère pas du tout la localisation avec un... bouton....

    Là encore, l'utilisation de Thread.sleep() doit mettre immédiatement la puce à l'oreille... si on utilise cette fonction, c'est qu'on a zappé un mode de communication par évènement.

    Lors de l'appui sur un bouton, nul ne sait l'état du réseau... et y attendre "une localisation" est complètement aléatoire.

    Si l'appui sur le bouton DOIT fournir une localisation, voici l'algorithme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    onResume:
       LocationManager setup + register(this) as location listener
       this.location = manager.getLastKnownLocation();
     
    onPause:
       unregister(this)... LocationManager disposal
     
    onClick:
       if (this.location == null) {
           this.locationWanted = true;
           showProgress();
       } else
           onLocated();
     
    onLocationChanged:
       this.location = newLocation; // attention, vérifier ici la cohérence (provider...).
       if (this.locationWanted) {
           hideProgress();
           onLocated();
       }
     
    onLocated:
       Toast... avec la location (jamais nulle)
    Pas besoin de 'sleep', de thread ou de 'task'.
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut
    Merci pour ta réponse =)

    J'ai donc suivis au mieu tes conseils et j'en suis arrivé au code suivant (qui se lance) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    public class MainActivity extends Activity implements LocationListener{
     
    	Button push = null;
    	static Location location;
    	static Context context;
    	static LocationManager lm;
     
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		context = getApplicationContext();
    		push = (Button)findViewById(R.id.boutton);
    		push.setOnClickListener(new OnClickListener() {
     
    			@Override
    			public void onClick(View arg0) {
    				if (location == null){
    					Toast.makeText(context, "Location est nul!", Toast.LENGTH_SHORT).show();
     
    				}else{
    					Toast.makeText(context, String.valueOf(location.getAltitude()), Toast.LENGTH_SHORT).show();
    				}
    			}
    		});
    	}
     
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.main, menu);
     
    		return true;
    	}
     
    	@Override
    	protected void onResume(){
    		super.onResume();
    		Criteria crit = new Criteria();
    		crit.setAccuracy(Criteria.ACCURACY_FINE);
    		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    		String best = lm.getBestProvider(crit, false);
    		lm.requestLocationUpdates(best, 1, 1, this);
    		location = lm.getLastKnownLocation(best);
    	}
     
    	@Override
    	protected void onPause(){
    		super.onPause();
    		//lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    		lm.removeUpdates(this);
    	}
     
    	@Override
    	public void onLocationChanged(Location arg0) {
    		Log.i("onLocationChanged", "debut");
    		location = arg0;
    	}
     
    	@Override
    	public void onProviderDisabled(String arg0) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void onProviderEnabled(String arg0) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
    		// TODO Auto-generated method stub
     
    	}
     
    }
    Mais je me retrouve avec mon problème de départ x)
    Mes coordonnées ne changent pas, le onLocationChanged est appelé de manière très rare (et donc, je me retrouve avec un location obsolète de plusieures minutes..).
    Lorsque je démarre ce bout de code, j'ai l'icone gps de mon téléphone qui clognote...et lorsqu'elle ne clognote plus (pendant 20/30 secondes toutes les 5/10/15 minutes et +), il n'y a aucun soucis la. Mes coordonnées changent chaque fois que je presse le bouton.

    Je commence à croire que c'est mon appareil qui déconne (HTC Desire HD au passage...)
    Estce que le code que j'éai écris présente un défaut ?

  5. #5
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Si j'ai bien compris tu demandes une localisation exclusivement basée sur le GPS (l'utilisation des autres sources de localisations peut grandement améliorer le positionnement).

    Quand l'icone GPS clignote c'est qu'il est en recherche de "fix" (au moins 3 satellites accrochés), donc aucune chance d'avoir des update GPS pendant ce temps là....
    Par contre, une fois les satellites "accrochés" tout devrait rouler correctement... Il faut peut-être améliorer la fonction "onLocationChanged" pour ne prendre en compte que les localisations "améliorées"... il y a un bout de code d'exemple sur Google:
    http://developer.android.com/guide/t...l#BestEstimate


    Tu fais bien tes tests en extérieur au moins ?
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut
    Oui c'est bien ça, j'aurai peut etre du expliquer le but du programme dès le départ :

    En fait, je souhaite qu'un utilisateur puisse capter ses coordonnées en pleine nature (donc dans le pire des cas, je ne peut que passer par du satellite). De plus, j'aimerai pouvoir garantir une nouvelle location au moins toutes les 5/10 mn (et à défaut de le garantir..le forcer le plus possible).

    Les tests sont fait près de ma fênetre habituellement..mais j'ai déjà testé mes bout de programmes en pleine rue :p

    Je découvre les joies de l'utilisation GPS en programmation, donc pas mal de points doivent m'échaper encore ...(comme le coup des 3 satellites accrochés ^^)
    Je testerai dans la soirée l'amélioration du onLocationChanged dont tu parles. Mais ayant regardé le code ..j'ai l'impression de faire la même chose que ma boucle while toute moche (je test la date de l'objet location). Bon au moins, je boufferai pas la batterie x)

    Merci en tout cas :p
    Je finierais ce post par cette dernière question :
    Il n'y a donc pas moyen de raccourcir le "rafraichissage" ? (hormis en jouant avec le requestLocationUpdates et onLocationChanged comme tu as suggéré)

Discussions similaires

  1. [Android 4.2.2 / GPS] onLocationChanged() jamais appelé
    Par Gob59 dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 19/08/2013, 13h19
  2. [JSF] Action methods jamais appelées
    Par mauvais_karma dans le forum JSF
    Réponses: 4
    Dernier message: 15/05/2007, 16h05
  3. Réponses: 7
    Dernier message: 19/04/2007, 18h54
  4. methode paint jamais appeller.
    Par Blo0d4x3 dans le forum 2D
    Réponses: 9
    Dernier message: 22/01/2006, 22h44
  5. [ Struts ] Erreur : l'action n'est jamais appelé
    Par romain3395 dans le forum Struts 1
    Réponses: 3
    Dernier message: 25/06/2004, 14h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo