2011-11-11 18 views
12

Ho un problema con la mia applicazione Android. Ho bisogno di un'applicazione che invierà la posizione GPS in background ogni 10 minuti al server (qui ho il servizio WCF che funziona). L'applicazione deve inviare dati anche se è chiusa. Così ho creato un servizio (a scopo di test) che mi invia l'ora sul server. Ma quando inserisco il mio codice per ottenere la posizione GPS nel mio servizio, tutto fallisce (interrotto inaspettatamente).Il servizio in background deve inviare la posizione GPS sul server

Ho canna che è necessario mettere qualche ricevitore o qualcosa, ma nulla finora funziona. Quindi sarò molto contento se qualcuno mi può aiutare.

<?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

"il mio servizio fallisce (interrotto in modo imprevisto)" -> qual è l'errore che si ottiene? – Hoff

+0

In CatLog ottengo questo: 11-11 15: 25: 49.541: E/AndroidRuntime (229): gestore non interrogato: thread principale in uscita a causa dell'eccezione non rilevata –

risposta

33

Ho fatto questo nella mia app per fare la stessa cosa che hai chiesto.

Nel mio servizio che ho aggiunto questo:

@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: vedere che io uso MyApplication.getAppContext(); perché sto usando la mia classe Application per aggiungere il contesto. E poi ho un BroadcastReceiver con questo:

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

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

anche nel vostro manifesto è necessario aggiungere sia:

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

metodo per rilevare se il servizio è in esecuzione Faccio questo sul mio primo attività:

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

Ovviamente è necessario controllare le SharedPreferences (impostazioni) per impostare la variabile locationService a true/false se il servizio è in esecuzione (onStart) o meno (OnDestroy).

+0

Sembra perfetto ma ho ancora problemi: questo xxx.yyy.intent. .. cosa mettere invece e ho anche problemi con quello MyApplication.getCOntext(), c'è qualche altro modo? –

+0

come ho detto Devi creare una classe che si estende dall'applicazione (e aggiungerla al tuo manifest) xxx.yyy.intent.action.LOCATION può essere qualsiasi cosa tu voglia .. come il nome del tuo pacchetto e aggiungere intent.action .LOCATION per essere più specifico su di esso .. Modificherò la mia risposta con la classe di applicazione – SERPRO

+0

OK ora ottengo: W/ActivityManager (51): Impossibile avviare il servizio Intent {act = com.biromatik.GPS.MonitorService}: non trovato. Puoi dirmi come iniziare quel servizio ora? –

Problemi correlati