¿Cómo puedo usar getSystemService en una clase sin actividad (LocationManager)?

181

Tengo problemas para descargar tareas del método principal Activities OnCreate en otra clase para hacer el trabajo pesado.

Cuando intento llamar a getSystemService desde la clase que no es de Actividad, se produce una excepción.

Cualquier ayuda sería muy apreciada :)

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
fuente
2
Añadiendo la excepción y Seguimiento de la pila a la pregunta puede ayudar a que responden potenciales
Bert F
Hola perdon por el error La excepción se produce si intento extender la clase Activity con esta. No quiero extender la clase Activity para esta clase y simplemente quiero poder llamar a getSystemService desde mi método getLocation. Excepción: java.lang.IllegalStateException: Servicios del sistema no disponibles para Actividades antes de onCreate ()
Kevin Parker

Respuestas:

280

Necesitas pasar tu contexto a tu clase fyl.
Una solución es hacer un constructor como este para tu fylclase:

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

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

       --
 }
}

Entonces, en su clase de actividad, cree el objeto de fyl en una onCreatefunción como esta:

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
fuente
Lo siento, no lo entiendo, el código sería más útil. En todo caso, debería pasar un objeto LocationManager al método getLocation ... Realmente no veo cómo pasar el contexto al método ayudará cuando ni siquiera puedo llamar a getSystemService sin escribir esta clase como una clase extendida en Activity.
Kevin Parker
¿Intentaste esto? En onCreate si está pasando, acceda al contexto por 'esto'
Labeeb Panampullan
pero si la lmtclase no se ejecuta, entonces flyno tendrá contexto
Hunt
Por cierto, getSysytemService()solo acepta Stringcomo parámetro. Por lo tanto, no puede pasarle un contexto. ¿Cómo puedo evitar esto? @Hunt
Parth Sane
2
Solo para mencionar, los administradores de Android ( BluetoothManager, ActivityManageretc.) también se construyen de esa manera (no necesariamente pasando un Activitycontexto a su constructor) y es por eso que pueden acceder a los componentes en el alcance de la aplicación.
Eido95
47

Puedes ir por esto:

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
Maddy
fuente
55
El método getActivity () no está definido para la clase. Este error aparece.
Darpan
¿Cuál es el tipo de clase en la que lo está usando? es decir, es una clase de receptor, fragmento, clase simple de Java o cualquier otra.
Maddy
Necesita extender su Actividad con FreagmentActivity en lugar de una Actividad. Espero que funcione para ti ...
Maddy
No funciona para una clase simple donde quiero extender ArrayAdapter.
David Silva-Barrera
2
¡MIne trabajó usando getContext () en lugar de getActivity ()!
Amir
16

Una forma de solucionar esto es creando una clase estática para instancias. Lo utilicé mucho en AS3. También me ha funcionado muy bien en el desarrollo de 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;
    }
    ...
}

Luego puede acceder al contexto o mediante Config.context

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = Config.context.getSystemService(context);
brenjt
fuente
44
El problema que veo con este método es que deja algo desprotegido que, si alguien le asignara un valor nulo, ¿probablemente produciría una falla catastrófica?
Rob
2
Una variación de esto es poner una estática privada en MyApp y luego agregar captadores. private static MyApp _context; public static MyApp getContext() { return _context; }... en onCreate: _context = this; en onStop: _context = null;... Uso: MyApp.getContext().
ToolmakerSteve
2
Es tal vez conduce a pérdida de memoria
Yat3s
2
Esto conducirá absolutamente a una pérdida de memoria. Idealmente, no deberías usar este proceso.
principiante
0

No sé si esto ayudará, pero hice esto:

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
Ruchir Baronia
fuente
La forma correcta es usar de forma estática, como dice
@Maddy
0

Para algunas clases que no son de actividad, como Worker , ya tienes un objeto Context en el constructor público.

Worker(Context context, WorkerParameters workerParams)

Puede usar eso, por ejemplo, guardarlo en una variable de contexto privada en la clase (por ejemplo, mContext) y luego, por ejemplo

mContext.getSystenService(Context.ACTIVITY_SERVICE)
auspicioso99
fuente