Comment puis-je utiliser getSystemService dans une classe sans activité (LocationManager)?

181

J'ai du mal à décharger les tâches de la méthode principale Activities OnCreate vers une autre classe pour faire le gros du travail.

Lorsque j'essaye d'appeler getSystemService à partir de la classe non-Activity, une exception est levée.

Toute aide serait grandement appréciée :)

lmt.java:

package com.atClass.lmt;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.location.Location;

public class lmt extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        fyl lfyl = new fyl();
        Location location = lfyl.getLocation();
        String latLongString = lfyl.updateWithNewLocation(location);

        TextView myLocationText = (TextView)findViewById(R.id.myLocationText);
        myLocationText.setText("Your current position is:\n" + latLongString);
    }
}

fyl.java

package com.atClass.lmt;

import android.app.Activity;
import android.os.Bundle;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.content.Context;

public class fyl {
    public Location getLocation(){
        LocationManager locationManager;
        String context = Context.LOCATION_SERVICE;
        locationManager = (LocationManager)getSystemService(context);

        String provider = LocationManager.GPS_PROVIDER;
        Location location = locationManager.getLastKnownLocation(provider);

        return location;
    }

    public String updateWithNewLocation(Location location) {
        String latLongString;

        if (location != null){
            double lat = location.getLatitude();
            double lng = location.getLongitude();
            latLongString = "Lat:" + lat + "\nLong:" + lng;
        }else{
            latLongString = "No Location";
        }

        return latLongString;
    }
}
Kevin Parker
la source
2
L'ajout de l'exception et de la trace de la pile à la question peut aider les répondants potentiels
Bert F
Salut, désolé pour l'erreur. L'exception est levée si j'essaie d'étendre la classe Activity avec celle-ci. Je ne veux pas étendre la classe Activity pour cette classe et je veux simplement pouvoir appeler getSystemService depuis ma méthode getLocation. Exception: java.lang.IllegalStateException: services système non disponibles pour les activités avant onCreate ()
Kevin Parker

Réponses:

280

Vous devez transmettre votre contexte à votre classe fyl.
Une solution est de créer un constructeur comme celui-ci pour votre fylclasse:

public class fyl {
 Context mContext;
 public fyl(Context mContext) {
       this.mContext = mContext;
 }

 public Location getLocation() {
       --
       locationManager = (LocationManager)mContext.getSystemService(context);

       --
 }
}

Donc, dans votre classe d'activité, créez l'objet de fyl en onCreatefonction comme ceci:

package com.atClass.lmt;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.location.Location;

public class lmt extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        fyl lfyl = new fyl(this); //Here the context is passing 

        Location location = lfyl.getLocation();
        String latLongString = lfyl.updateWithNewLocation(location);

        TextView myLocationText = (TextView)findViewById(R.id.myLocationText);
        myLocationText.setText("Your current position is:\n" + latLongString);
    }
}
Labeeb Panampullan
la source
Désolé, je ne comprends pas, le code serait plus utile. Si quoi que ce soit, je devrais passer un objet LocationManager à la méthode getLocation ... Je ne vois pas vraiment comment le fait de passer le contexte à la méthode m'aidera quand je ne peux même pas appeler getSystemService sans écrire cette classe comme une classe étendue à Activity.
Kevin Parker
avez-vous essayé cela. Dans le onCreate si vous passez, accédez au contexte par 'this'
Labeeb Panampullan
mais si la lmtclasse ne sera pas exécutée, alors flyn'aura pas de contexte
Chasse
BTW getSysytemService()n'accepte Stringque comme paramètre. Par conséquent, vous ne pouvez pas lui passer de contexte. Comment puis-je contourner cela? @Hunt
Parth Sane
2
Juste pour mentionner, les gestionnaires Android ( BluetoothManager, ActivityManageretc.) sont également construits de cette façon (ne passant pas nécessairement un Activitycontexte à leur constructeur) et c'est pourquoi ils peuvent accéder aux composants dans la portée de l'application.
Eido95
47

Vous pouvez opter pour ceci:

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
Maddy
la source
5
La méthode getActivity () n'est pas définie pour la classe. Cette erreur apparaît.
Darpan
Quel est le type de classe dans lequel vous l'utilisez? c'est-à-dire que c'est une classe de récepteur, un fragment, une classe java simple ou tout autre.
Maddy
Vous devez étendre votre activité avec FreagmentActivity au lieu d'une activité. J'espère que cela fonctionnera pour vous ...?
Maddy
Cela ne fonctionne pas pour une classe simple où je veux étendre ArrayAdapter.
David Silva-Barrera le
2
MIne fonctionnait en utilisant getContext () au lieu de getActivity ()!
Amir
16

Une façon de contourner ce problème est de créer une classe statique pour les instances. Je l'ai beaucoup utilisé en AS3, j'ai aussi très bien travaillé pour moi dans le développement Android.

Config.java

public final class Config {
    public static MyApp context = null;
}

MyApp.java

public class MyApp extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Config.context = this;
    }
    ...
}

Vous pouvez ensuite accéder au contexte ou en utilisant Config.context

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = Config.context.getSystemService(context);
brenjt
la source
4
Le problème que je vois avec cette méthode est qu'elle laisse quelque chose de non protégé qui, si quelqu'un lui attribuait null, produirait probablement un échec catastrophique?
Rob
2
Une variante à cela consiste à mettre une statique privée dans MyApp, puis à ajouter des getters. private static MyApp _context; public static MyApp getContext() { return _context; }... en onCreate: _context = this; en onStop: _context = null;... Utilisation: MyApp.getContext().
ToolmakerSteve
2
Cela peut conduire à une fuite de mémoire
Yat3s
2
Cela entraînera absolument une fuite de mémoire. Idéalement, vous ne devriez pas utiliser ce processus.
débutant
0

Je ne sais pas si cela aidera, mais j'ai fait ceci:

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
Ruchir Baronia
la source
La bonne façon est d'utiliser de manière statique, comme le dit
@Maddy
0

Pour certaines classes sans activité, comme Worker , vous disposez déjà d'un objet Context dans le constructeur public.

Worker(Context context, WorkerParameters workerParams)

Vous pouvez simplement l'utiliser, par exemple, l'enregistrer dans une variable de contexte privée dans la classe (par exemple, mContext), puis, par exemple

mContext.getSystenService(Context.ACTIVITY_SERVICE)
de bon augure99
la source