Android Context sin estar en una actividad? ¿Y otra programación sin actividad?

Voy a tratar de convertirlo en una pregunta exhaustiva:

Estoy escribiendo un método para obtener una cadena que contenga el nombre de la ciudad de un dispositivo Android, según determine el LocationManager y getLastKnownLocation() y todo eso.

Entonces me di cuenta de que tendría que hacer lo mismo de nuevo en otra actividad, así que ¿por qué no hacer una clase totalmente separada ( LocationFinder ) que podría utilizar a través de mi programa, en lugar de escribir código duplicado en todas partes?

Pero me he topado con problemas que me confunden. Por ejemplo, si hago esta clase ( LocationFinder ), ¿debería extender la Actividad, aunque nunca se visualice? Todo lo que esta clase haría es tener una variedad de getters como getLastKnownCity() o getCurrentCity() y devolver cadenas. Asumí que no tendría que ampliar la clase de actividad, ya que realmente no es una actividad.

Pero entonces, ¿qué contexto utilizo para:

 Geocoder geocoder = new Geocoder(Context context, Locale locale) 

?

Esto me hizo asumir que debe ser una actividad. Así que extendí la actividad y reemplazé al constructor por

 @Override protected void onCreate(.............. 

Pero por alguna razón, que nunca termina siendo llamado, incluso cuando pongo

 String city = new LocationFinder().getLastKnownCity(); 

Mi primera línea de onCreate() de LocationFinder es

 System.out.println("HEY!") 

Y nunca llega a eso. Obtengo un puntero nulo en android.internal.os.LoggingPrintStream.println() y otras cosas.

Además, hay un montón de constantes del sistema que provienen de clases de actividad. Por ejemplo, necesito llegar a LOCATION_SERVICE , que es una cadena, que no puedo obtener sin extender la actividad. Claro, yo podría engañar y acaba de poner en la cadena literal, pero que se siente mal.

Al construir su clase, usted puede tener un constructor que toma en un contexto y le asigna un objeto de contexto local dentro de su clase.

 public class LocationFinder { private Context myContext; private Geocoder geocoder; public LocationFinder(Context context) { myContext = context; geocoder = new Geocoder(myContext); } } 

Y luego, cuando intentes acceder a esta clase, asegúrate de inicializarla como:

 public class TestActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LocationFinder lFinder = new LocationFinder(getApplication()); } } 

Por supuesto, no puede acceder a un contexto de cada clase que va a ejecutar. Así que una referencia a una vista puede bastar.

 LocationFinder lFinder = new LocationFinder(anyView.getApplication()); 

EDIT: Si es posible, utilice la respuesta de frogmanx. Esto sólo se debe utilizar cuando su respuesta no es posible de usar. (Es decir, singletons que necesitan un contexto justo al bate).

Suena como que debe extender la aplicación y no la actividad.

Haga su aplicación algo como esto:

 public class MyApplication extends Application { private static MyApplication instance; public MyApplication() { instance = this; } public static MyApplication getInstance() { return instance; } 

A continuación, agregue este atributo a la etiqueta de aplicación del manifiesto:

  <application android:name=".your.package.MyApplication" ... /> 

Después de todo eso, puede obtener un Contexto llamando a MyApplication.getInstance() desde cualquier lugar.

 should it extend Activity, even though it is never actually visualized? 

No. Desde los documentos Android

Una actividad es una cosa única y enfocada que el usuario puede hacer. Casi todas las actividades interactúan con el usuario, por lo que la clase de actividad se encarga de crear una ventana para usted en la que puede colocar su interfaz de usuario con setContentView (View)

Piense en una actividad como una pantalla que el usuario ve.

Pero entonces, ¿qué contexto utilizo Geocoder geocoder = new Geocoder (Contexto contextual, localidad regional)

La clase Activity extiende Context , al igual que muchas otras clases incluyendo Application . Un contexto proporciona acceso a recursos asociados con la clase que extiende el contexto.

Sólo necesita y debe usar un contexto de Actividad cuando sea necesario para interactuar con los recursos asociados con esa Actividad y los métodos implementados por la clase de actividad concreta. Cuando necesite ese acceso a ese contexto, entonces lo pasará a la clase que necesite acceso, normalmente como un argumento para un constructor de esa clase.

Si alguna vez pasa un contexto de Actividad fuera de la actividad que lo extiende, asegúrese de que el alcance y el ciclo de vida de la referencia sea menor o igual que la actividad que se extiende, de lo contrario perderá grandes cantidades de memoria si la actividad se destruye ya que la basura El colector no puede liberar la memoria ya que hay una referencia al contexto.

Si echa un vistazo al constructor de Geocoder verá que toma un Contexto como un argumento, como usted sabe. Hay una pista de por qué el Contexto es necesario en la descripción:

  Geocoder(Context context, Locale locale) Constructs a Geocoder whose responses will be localized for the given Locale. [1]: 

La razón por la que se requiere el Contexto es obtener acceso a la información del sistema sobre las configuraciones regionales de la plataforma y la configuración regional actual del sistema.

Así que en su ejemplo, simplemente podría pasar el contexto de la aplicación al constructor, que puede obtener una referencia a con getApplicationContext()

Por ejemplo, necesito llegar a LOCATION_SERVICE, que es una cadena, que no puedo obtener sin extender la actividad

Puede obtenerlo desde el contexto de la aplicación.

  • Android gps proveedor y gps icono
  • Android: Obtener ubicación reciente solamente, no getLastKnownLocation?
  • Cálculo de distancia desde mi ubicación hasta la ubicación de destino en android
  • Android: compruebe si los servicios de ubicación están habilitados utilizando el proveedor de ubicación fusionado
  • Android Compass señala mi ubicación en lugar de norte
  • LocationRequest desplazamiento más pequeño y precisión
  • ¿Cómo encontrar mi ubicación actual (latitute + longitude) al hacer clic en un botón en android?
  • Calcular la distancia entre dos ubicaciones geográficas
  • Diferencia entre LocationRequest setInterval (long millis) y LocationRequest setFastestInterval (long millis)
  • Número GPS de satélites y filtrado de ubicaciones
  • ¿Cuál es el significado de dbm negativo en la fuerza de la señal?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.