Come posso usare getSystemService in una classe non di attività (LocationManager)?


181

Ho problemi a scaricare le attività dal metodo principale di Attività su creazione in un'altra classe per eseguire il lavoro pesante.

Quando provo a chiamare getSystemService dalla classe non Activity, viene generata un'eccezione.

Qualsiasi aiuto sarebbe molto apprezzato :)

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

2
L'aggiunta dell'eccezione e la traccia dello stack alla domanda possono aiutare i potenziali rispondenti
Bert F

Ciao, scusami per l'errore. L'eccezione viene generata se provo a estendere la classe Activity con questa. Non voglio estendere la classe Activity per questa classe e voglio semplicemente essere in grado di chiamare getSystemService dal mio metodo getLocation. Eccezione: java.lang.IllegalStateException: servizi di sistema non disponibili per Attività prima di onCreate ()
Kevin Parker

Risposte:


280

Devi passare il tuo contesto alla tua classe fyl.
Una soluzione è creare un costruttore come questo per la tua fylclasse:

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

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

       --
 }
}

Quindi nella tua classe di attività crea l'oggetto di fyl in una onCreatefunzione come questa:

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

Mi dispiace non capisco, il codice sarebbe più utile. Semmai dovrei passare un oggetto LocationManager al metodo getLocation ... Non vedo davvero come il passaggio del contesto al metodo mi aiuterà quando non riesco nemmeno a chiamare getSystemService senza scrivere questa classe come classe estesa su Activity.
Kevin Parker,

hai provato questo. In onCreate se stai passando accedi al contesto tramite 'this'
Labeeb Panampullan,

ma se la lmtclasse non verrà eseguita, allora flynon avrà contesto
Hunt

BTW getSysytemService()accetta solo Stringcome parametro. Pertanto non è possibile passare un contesto ad esso. Come posso aggirare questo? @Hunt
Parth Sane,

2
Solo per citare, anche i gestori Android ( BluetoothManager, ActivityManagerecc.) Sono costruiti in questo modo (non necessariamente passando un Activitycontesto al loro costruttore) ed è per questo che possono accedere ai componenti nell'ambito dell'applicazione.
Eido95

47

Puoi andare per questo:

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);

5
Il metodo getActivity () non è definito per la classe. Questo errore si presenta.
Darpan,

Qual è il tipo di classe in cui lo stai usando? cioè è una classe ricevente, un frammento, una semplice classe java o qualsiasi altra.
Maddy,

Devi estendere la tua attività con FreagmentActivity anziché un'attività. Spero che funzionerà per te ...?
Maddy,

Non funziona per una semplice classe in cui voglio estendere ArrayAdapter.
David Silva-Barrera,

2
MI ha funzionato usando getContext () invece di getActivity ()!
Amir,

16

Un modo per aggirare il problema è creare una classe statica per le istanze. L'ho usato molto in AS3, ho funzionato benissimo anche per me nello sviluppo 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;
    }
    ...
}

È quindi possibile accedere al contesto o utilizzando Config.context

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = Config.context.getSystemService(context);

4
Il problema che vedo con questo metodo è che lascia qualcosa di non protetto che, se qualcuno gli assegnasse null, probabilmente produrrebbe un fallimento catastrofico?
Rob, il

2
Una variazione su questo è mettere un statico privato in MyApp e quindi aggiungere getter. private static MyApp _context; public static MyApp getContext() { return _context; }... in onCreate: _context = this; in onStop: _context = null;... Uso: MyApp.getContext().
ToolmakerSteve

2
Potrebbe portare a una perdita di memoria
Yat3s,

2
Questo porterà assolutamente alla perdita di memoria. Idealmente non dovresti usare questo processo.
principiante,

0

Non so se questo aiuterà, ma ho fatto questo:

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);

Il modo giusto è quello di utilizzare in modo statico, come dice @
Maddy

0

Per alcune classi non di attività, come Lavoratore , ti è già stato assegnato un oggetto Context nel costruttore pubblico.

Worker(Context context, WorkerParameters workerParams)

Puoi semplicemente usarlo, ad esempio, salvarlo in una variabile di contesto privata nella classe (diciamo, mContext) e quindi, ad esempio

mContext.getSystenService(Context.ACTIVITY_SERVICE)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.