2011-11-11 18 views
12

Tengo un problema con mi aplicación Android. Necesito una aplicación que envíe la ubicación de fondo del GPS cada 10 minutos al servidor (aquí tengo el servicio WCF que funciona). La aplicación necesita enviar datos incluso si está cerrada. Así que creé un servicio (para fines de prueba) que me envía tiempo en el servidor. Pero cuando inserto mi código para obtener la ubicación del GPS en mi servicio, todo falla (se detiene inesperadamente).El servicio en segundo plano necesita enviar la ubicación del GPS en el servidor

Tengo una caña que necesita poner un receptor o algo pero hasta ahora nada funciona. Así que estaré muy contento si alguien puede ayudarme.

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.biromatik.GPS" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="4" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:label="@string/app_name" 
      android:name=".ETMGPSServiceActivity" > 
      <intent-filter > 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 
    <application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:name=".MyApplication" > 
    <service 
     android:enabled="true" 
     android:name=".MonitorService" > 
    </service> 
    <receiver 
     android:enabled="true" 
     android:name=".LocationReceiver" > 
     <intent-filter > 
      <action android:name="com.biromatik.intent.action.LOCATION" /> 
     </intent-filter> 
    </receiver> 
</application> 


    <uses-permission android:name="android.permission.INTERNET"></uses-permission> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 




</manifest> 
+0

"mi servicio falló todo (se detuvo inesperadamente)" -> ¿cuál es el error que está obteniendo? – Hoff

+0

En CatLog obtengo esto: 11-11 15: 25: 49.541: E/AndroidRuntime (229): controlador no capturado: el hilo principal sale debido a una excepción no detectada –

Respuesta

33

He hecho esto en mi aplicación para hacer lo mismo que ha pedido.

En mi servicio que añade esto:

@Override 
public void onStart(Intent intent, int startId) { 

    super.onStart(intent, startId); 
    addLocationListener(); 
} 

private void addLocationListener() 
{ 
    triggerService = new Thread(new Runnable(){ 
     public void run(){ 
      try{ 
       Looper.prepare();//Initialise the current thread as a looper. 
       lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 

       Criteria c = new Criteria(); 
       c.setAccuracy(Criteria.ACCURACY_COARSE); 

       final String PROVIDER = lm.getBestProvider(c, true); 

       MyLocationListener myLocationListener = new MyLocationListener(); 
       lm.requestLocationUpdates(PROVIDER, 600000, 0, myLocationListener); 
       Log.d("LOC_SERVICE", "Service RUNNING!"); 
       Looper.loop(); 
      }catch(Exception ex){ 
       ex.printStackTrace(); 
      } 
     } 
    }, "LocationThread"); 
    triggerService.start(); 
} 

public static void updateLocation(Location location) 
{ 
    Context appCtx = MyApplication.getAppContext(); 

    double latitude, longitude; 

    latitude = location.getLatitude(); 
    longitude = location.getLongitude(); 

    Intent filterRes = new Intent(); 
    filterRes.setAction("xxx.yyy.intent.action.LOCATION"); 
    filterRes.putExtra("latitude", latitude); 
    filterRes.putExtra("longitude", longitude); 
    appCtx.sendBroadcast(filterRes); 
} 


class MyLocationListener implements LocationListener 
{ 

    @Override 
    public void onLocationChanged(Location location) 
    { 
     updateLocation(location); 
    } 
} 

NOTA: ver que yo uso MyApplication.getAppContext(); eso es porque estoy usando mi propia clase de aplicación para agregar el contexto. Y entonces tengo una BroadcastReceiver con esto:

public class LocationReceiver extends BroadcastReceiver { 

    double latitude, longitude; 

    @Override 
    public void onReceive(final Context context, final Intent calledIntent) 
    { 
     Log.d("LOC_RECEIVER", "Location RECEIVED!"); 

     latitude = calledIntent.getDoubleExtra("latitude", -1); 
     longitude = calledIntent.getDoubleExtra("longitude", -1); 

     updateRemote(latitude, longitude); 

    } 

    private void updateRemote(final double latitude, final double longitude) 
    { 
     //HERE YOU CAN PUT YOUR ASYNCTASK TO UPDATE THE LOCATION ON YOUR SERVER 
    } 
} 

la clase Application:

public class MyApplication extends Application { 


    private static Context context; 

    /* (non-Javadoc) 
    * @see android.app.Application#onCreate() 
    */ 
    @Override 
    public void onCreate() {    
     MyApplication.context=getApplicationContext(); 
    } 

    public static Context getAppContext() { 
     return MyApplication.context; 
    } 
} 

También en el manifiesto es necesario agregar tanto:

<application 
    android:icon="@drawable/icon" 
    android:label="@string/app_name" 
    android:name=".MyApplication" > 

    //YOUR ACTIVITIES HERE... 

    <service 
     android:enabled="true" 
     android:name=".LocationService" > 
    </service> 

    <receiver 
     android:enabled="true" 
     android:name=".LocationReceiver" > 
     <intent-filter > 
      <action android:name="xxx.yyy.intent.action.LOCATION" /> 
     </intent-filter> 
    </receiver> 
</application> 

Método para detectar si el servicio se está ejecutando. Lo hago en mi primera actividad:

/** 
* Check location service. 
*/ 
private void checkLocationService() 
{ 
    Log.d("CHECK_SERVICE", "Service running: " + (settings.getBoolean("locationService", false)?"YES":"NO")); 

    if(settings.getBoolean("locationService", false)) 
     return; 

    Intent mServiceIntent = new Intent(this, LocationService.class); 
    startService(mServiceIntent); 
} 

Obviamente se necesita para controlar los ajustes SharedPreferences () para establecer la variable locationService a verdadero/falso si el servicio se está ejecutando (onStart) o no (OnDestroy).

+0

Eso se ve perfecto, pero todavía tengo problemas: este xxx.yyy.intent. ... qué poner en su lugar y también tengo un problema con MyApplication.getCOntext(), ¿hay alguna otra manera? –

+0

como dije Necesitas crear una clase que se extienda desde la Aplicación (y agregarla a tu manifiesto) la xxx.yyy.intent.action.LOCATION puede ser lo que quieras ... como el nombre de tu paquete y agregar intent.action .LOCATION para ser más específico al respecto ... Editaré mi respuesta con la clase de aplicación – SERPRO

+0

Ahora bien, obtengo: W/ActivityManager (51): no se puede iniciar el servicio Intención {act = com.biromatik.GPS.MonitorService}: extraviado. ¿Puedes decirme cómo comenzar ese servicio ahora? –

Cuestiones relacionadas