Как я могу использовать getSystemService в классе без активности (LocationManager)?

181

У меня проблемы с выгрузкой задач из основного метода Activity OnCreate в другой класс для выполнения тяжелой работы.

Когда я пытаюсь вызвать getSystemService из класса не-Activity, возникает исключение.

Любая помощь будет принята с благодарностью :)

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
Добавление исключения и трассировки стека к вопросу может помочь потенциальным ответчикам
Берт Ф.
Привет, извините за ошибку. Исключение выдается, если я пытаюсь расширить класс Activity с этим. Я не хочу расширять класс Activity для этого класса и просто хочу иметь возможность вызывать getSystemService из моего метода getLocation. Исключение: java.lang.IllegalStateException: системные службы недоступны для операций перед onCreate ()
Кевин Паркер

Ответы:

280

Вам нужно передать свой контекст вашему классу fyl.
Одним из решений является создание конструктора, подобного этому, для вашего fylкласса:

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

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

       --
 }
}

Итак, в вашем классе деятельности создайте объект fyl в onCreateфункции следующим образом:

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);
    }
}
Лабиб Панампуллан
источник
Извините, я не понимаю, код будет более полезным. Если что-то мне нужно передать объект LocationManager в метод getLocation ... Я действительно не понимаю, как мне поможет передача контекста в метод, когда я даже не могу вызвать getSystemService без записи этого класса как расширенного класса в Activity.
Кевин Паркер
ты пробовал это. В onCreate, если вы передаете доступ к контексту через 'this'
Лабиб Панампуллан,
но если lmtкласс не будет выполнен, тогда не flyбудет контекста
Hunt
Кстати, getSysytemService()принимает только Stringв качестве параметра. Поэтому вы не можете передать ему контекст. Как мне обойти это? @ Hunt
Sane
2
Просто упомянуть, Android - менеджеры ( BluetoothManager, и ActivityManagerт.д.), также построены таким образом (не обязательно пропускание Activityконтекста их конструктора) , и именно поэтому они могут получить доступ компонентов в рамках приложении.
Eido95
47

Вы можете пойти на это:

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
Мэдди
источник
5
Метод getActivity () для класса не определен. Эта ошибка обнаруживается.
Дарпан
Какой тип класса вы используете? то есть это класс получателя, фрагмент, простой класс Java или любой другой.
Мэдди
Вам нужно расширить свою деятельность с помощью FreagmentActivity вместо действия. Я надеюсь, что это сработает для вас ...?
Мэдди
Это не работает для простого класса, где я хочу расширить ArrayAdapter.
Дэвид Сильва-Баррера,
2
Мы работали, используя getContext () вместо getActivity ()!
Амир
16

Один из способов обойти это - создать статический класс для экземпляров. Я много использовал в AS3. Я отлично поработал и в разработке под 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;
    }
    ...
}

Затем вы можете получить доступ к контексту или с помощью Config.context

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = Config.context.getSystemService(context);
brenjt
источник
4
Проблема, которую я вижу с этим методом, заключается в том, что он оставляет что-то незащищенным, что, если бы кто-то присвоил ему значение null, могло бы привести к катастрофическому отказу?
Роб
2
Разновидностью этого является размещение приватной статики в MyApp, а затем добавление геттеров. private static MyApp _context; public static MyApp getContext() { return _context; }... в OnCreate: _context = this; в OnStop: _context = null;... Использование: MyApp.getContext().
ToolmakerSteve
2
Это может привести к утечке памяти
Yat3s
2
Это абсолютно приведет к утечке памяти. В идеале вы не должны использовать этот процесс.
начинающий
0

Я не знаю, поможет ли это, но я сделал это:

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
Ручир Барония
источник
Правильный путь - использовать статически, как говорит
@Maddy
0

Для некоторых неактивных классов, таких как Worker , вы уже получили объект Context в открытом конструкторе.

Worker(Context context, WorkerParameters workerParams)

Вы можете просто использовать это, например, сохранить его в закрытой переменной Context в классе (скажем, mContext), а затем, например,

mContext.getSystenService(Context.ACTIVITY_SERVICE)
auspicious99
источник