Jak korzystać z getSystemService w klasie niedziałającej (LocationManager)?

181

Mam problem z odciążeniem zadań z głównej metody Działania OnCreate do innej klasy w celu wykonania ciężkiego podnoszenia.

Kiedy próbuję wywołać getSystemService z klasy niedziałającej, zgłaszany jest wyjątek.

Każda pomoc byłaby bardzo mile widziana :)

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
źródło
2
Dodanie wyjątku i śledzenia stosu do pytania może pomóc potencjalnym użytkownikom odpowiadającym
Bert F
Cześć, przepraszam za błąd. Zgłaszany jest wyjątek, jeśli spróbuję rozszerzyć klasę Activity o tę. Nie chcę rozszerzać klasy Activity dla tej klasy i po prostu chcę móc wywoływać getSystemService z poziomu mojej metody getLocation. Wyjątek: java.lang.IllegalStateException: Usługi systemowe niedostępne dla działań przed onCreate ()
Kevin Parker

Odpowiedzi:

280

Musisz przekazać swój kontekst do swojej klasy fyl.
Jednym z rozwiązań jest stworzenie takiego konstruktora dla swojej fylklasy:

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

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

       --
 }
}

Więc w swojej klasie aktywności utwórz obiekt fyl w onCreatefunkcji w następujący sposób:

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
źródło
Niestety nie rozumiem, kod byłby bardziej pomocny. Jeśli cokolwiek powinienem przekazać obiekt LocationManager do metody getLocation ... Naprawdę nie widzę, jak przekazanie kontekstu do metody pomoże, gdy nie będę mógł nawet wywołać getSystemService bez zapisania tej klasy jako rozszerzonej klasy do działania.
Kevin Parker
próbowałeś tego? W polu onCreate, jeśli przechodzisz, uzyskujesz dostęp do kontekstu przez „this”
Labeeb Panampullan
ale jeśli lmtklasa nie zostanie wykonana, flynie będzie miał kontekstu
Poluj
BTW getSysytemService()akceptuje tylko Stringjako parametr. Dlatego nie możesz przekazać kontekstu. Jak to obejść? @Hunt
Parth Sane
2
Wystarczy wspomnieć, menedżerów (Android BluetoothManager, ActivityManageritp) także są skonstruowane w ten sposób (niekoniecznie przechodzącą Activitykontekst ich konstruktora) i dlatego mogą uzyskać dostęp do komponentów w zakresie aplikacji.
Eido95
47

Możesz to zrobić:

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
Maddy
źródło
5
Metoda getActivity () jest niezdefiniowana dla klasy. Ten błąd pojawia się.
Darpan
Jaki jest typ klasy, w której go używasz? tzn. jest to klasa odbiorcza, fragment, prosta klasa Java lub dowolna inna.
Maddy
Musisz rozszerzyć swoją działalność o FreagmentActivity zamiast działania. Mam nadzieję, że ci się uda ...?
Maddy,
Nie działa w przypadku prostej klasy, w której chcę rozszerzyć ArrayAdapter.
David Silva-Barrera,
2
MIne pracował przy użyciu getContext () zamiast getActivity ()!
Amir
16

Jednym ze sposobów na obejście tego jest stworzenie statycznej klasy dla instancji. Dużo go używałem w AS3. Świetnie dla mnie pracowałem także w rozwoju Androida.

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;
    }
    ...
}

Następnie możesz uzyskać dostęp do kontekstu lub za pomocą Config.context

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = Config.context.getSystemService(context);
brenjt
źródło
4
Problem, który widzę w tej metodzie, polega na tym, że pozostawia coś niechronionego, co, gdyby ktoś przypisał jej wartość zerową, prawdopodobnie spowodowałoby katastrofalną awarię?
Rob
2
Odmianą tego jest umieszczenie prywatnego statycznego w MyApp, a następnie dodanie pobierających. private static MyApp _context; public static MyApp getContext() { return _context; }... w onCreate: _context = this; w OnStop: _context = null;... Sposób użycia: MyApp.getContext().
ToolmakerSteve
2
Może to prowadzić do wycieku pamięci
Yat3s
2
To absolutnie doprowadzi do wycieku pamięci. Idealnie nie powinieneś używać tego procesu.
początkujący
0

Nie wiem, czy to pomoże, ale zrobiłem to:

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
Ruchir Baronia
źródło
Właściwym sposobem jest użycie w sposób statyczny, jak mówi
@Maddy
0

W przypadku niektórych klas niedziałających, takich jak Worker , masz już obiekt Context w konstruktorze publicznym.

Worker(Context context, WorkerParameters workerParams)

Możesz po prostu tego użyć, np. Zapisać go w prywatnej zmiennej kontekstowej w klasie (powiedzmy mContext), a następnie na przykład

mContext.getSystenService(Context.ACTIVITY_SERVICE)
pomyślny99
źródło