定期检索地理位置

时间:2014-08-11 22:36:50

标签: android geolocation

我正在开发一个应该定期发送用户地理位置的应用程序(间隔3分钟)。我正在阅读android文档,并想知道我是否需要在我拥有的每个活动/片段上创建一个LocationListener。

我正在考虑类似于一个像“沉默线程”一样运行的观察者。与应用程序一起将数据发送到我的服务。是否有类似的东西,或者我必须在每个地方实现LocationListener?

提前感谢。

1 个答案:

答案 0 :(得分:1)

我有一些具有相同requeriment的实现,还要记住设备在找到时可能会失去连接,因此您可能会考虑在sqlite中实现保存位置。它看起来像这样:

WakefulAlarmListener.java

import java.util.Calendar;

import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.StrictMode;
import android.util.Log;

import com.commonsware.cwac.wakeful.WakefulIntentService;
import com.commonsware.cwac.wakeful.WakefulIntentService.AlarmListener;

/*
 * 
 * 
 * @see <a> href="https://github.com/commonsguy/cwac-wakeful">https://github.com/commonsguy/cwac-wakeful</a>
 * @see {@link AutoSendingWakefulIntentService}
 * 
 */
public class WakefulAlarmListener implements AlarmListener {


    @Override
    public void scheduleAlarms(AlarmManager alarmManager,PendingIntent pendingIntent, Context context) 
    {
        IOController ioController = new IOController(context);
        int autoSendingFrequency = Integer.parseInt(context.getString(R.string.default_autosending_frequency));
        // Este método permite que se puedan realizar operaciones de
        // red en el hilo de la interfaz gráfica (El alarmlistener se ejecuta en este hilo).
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) 
        {
            Log.d("WakefulAlarmListener => scheduleAlarms()", "Build version: "
                    + Build.VERSION.SDK_INT + " >= "
                    + Build.VERSION_CODES.GINGERBREAD
                    + " => setting thread policy...");
            setThreadPolicy();
        }       

        alarmManager.cancel(pendingIntent);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Calendar
                .getInstance().getTimeInMillis(), autoSendingFrequency * 1000, pendingIntent);
    }


    @Override
    public void sendWakefulWork(Context context) {

        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.FROYO) 
        {
            context.startService(new Intent(context,LocationListenerDummyService.class));
        }                   
        IOController ioController = new IOController(context);
        int autoSendingFrequency = ioController.loadAutoSendingFrequency();
        int lastAutoSendingFrequency = ioController.loadLastAutoSendingFrequency();     
        if (autoSendingFrequency != -1)         
        {
            Log.d("sendWakefulWork()", "autoSendingFrequency=" + autoSendingFrequency);
            Log.d("sendWakefulWork()","lastAutoSendingFrequency=" + lastAutoSendingFrequency);
            if (autoSendingFrequency != lastAutoSendingFrequency) 
            {               
                WakefulIntentService.cancelAlarms(context);
                WakefulIntentService.scheduleAlarms(this, context);
            }
            else 
            {
                Log.d("sendWakefulWork()","autoSendingFrequency == lastAutoSendingFrequency");              
                WakefulIntentService.sendWakefulWork(context,AutoSendingWakefulIntentService.class);
            }
        } 
        else 
        {
            WakefulIntentService.cancelAlarms(context);
            WakefulIntentService.scheduleAlarms(this, context);
            Log.d("sendWakefulWork()","autoSendingFrequency == -1");
        }
    }

    /**
     * Si detecta que la alarma no se lanzó en el número de milisegundos
     * devuelto, entonces asume que el usuario cerró la aplicación de forma
     * forzada y vuelve a programar la alarma.
     * 
     * Consultar la documentación de la biblioteca para más información.
     * 
     * @return Tiempo en milisegundos. En este caso es de 0 milisegundos.
     * 
     */
    @Override
    public long getMaxAge() {
        return 0;
    }

    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    private void setThreadPolicy() {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }

}

AutosendeindWakefulIntenService.java

public class AutoSendingWakefulIntentService extends WakefulIntentService {


MDRCController myMDRC;

public AutoSendingWakefulIntentService() {
    super("AutoSendingWakefulIntentService");
}


@Override
protected void doWakefulWork(Intent intent) {               

    int timeout = Integer.parseInt((getString(R.string.autosending_timeout)));
    int sampleSize = Integer.parseInt((getString(R.string.autosending_samplesize)));
    boolean useNetworkLocation = Boolean.parseBoolean((getString(R.string.use_network_location_provider)));             
    int autoSendingTries = Integer.parseInt(getString(R.string.autosending_connection_tries));
    final WifiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
    IOController myIO =new IOController(getApplicationContext());
    MyLocation myLocation = new MyLocation(getApplicationContext(),timeout, sampleSize, useNetworkLocation);

    Location location = null;                                                   
    location = myLocation.getLocation();

    sendLocationToServer(location, autoSendingTries);               
    sendPendingGeoEventToServerAndUpdateCollection();                       
    verifyBatteryLevel();
}

private void sendLocationToServer(Location location, int autoSendingTries) {

    IOController myIo= new IOController(getApplicationContext());
    ServerResponseParser serverResponseParser = new ServerResponseParser(getApplicationContext());      
    SQLDataSource mySqlDataSource = new SQLDataSource(getApplicationContext());     
    String type;
    int actioncode=0;

    Log.d("AutoSendingWakefulIntentService => sendLocationToServer()","Auto Sending Tries: " + autoSendingTries);
        if (location != null) 
        {               
            if (autoSendingTries > 0)                   
            {   
                myIo.saveLastLocationData(location);                    
                Log.d("AutoSendingWakefulIntentService => sendLocationToServer()",
                                   "Latitude: " + location.getLatitude()
                                + "; Longitude: " + location.getLongitude()
                                + "; Accuracy: " + location.getAccuracy());                            
                 if(location.getProvider().equals(LocationManager.GPS_PROVIDER)) 
                 {
                   Log.d("AutoSending","GPS");
                   actioncode = Integer.parseInt(getApplicationContext().getResources().getString(R.string.actioncode_automatic_gps), 16);                                             
                   GeoEvent myGeoEvent = new GeoEvent(location, actioncode, new  DeviceInformation(getApplicationContext()).getBatteryLevel());         
                        //FIXME  sendGeoEventToServer() ;                                      
                 }
                 else
                {
                    if(location.getProvider().equals(LocationManager.NETWORK_PROVIDER))

                   {
                       try {
                             type =location.getExtras().getString("networkLocationType");
                            }catch(NullPointerException ex){                         
                             type ="network";
                            }
                       if(type.equalsIgnoreCase("wifi") && !myIo.loadWifiForLocation())
                           {
                            Log.d("AutoSending","wifi");
                             actioncode = Integer.parseInt(getApplicationContext().getResources().getString(R.string.actioncode_automatic_passive),16);    
                           }
                       else
                           {
                            Log.d("AutoSending","network");
                            actioncode = Integer.parseInt(getApplicationContext().getResources().getString(R.string.actioncode_automatic_network),16);
                           }

                       GeoEvent myGeoEvent = new GeoEvent(location, actioncode, new  DeviceInformation(getApplicationContext()).getBatteryLevel());
                        mySqlDataSource.InsertGeoEvent(myGeoEvent);
                       //FIXME  sendGeoEventToServer()  ;                                      
                   } 
                 else if(location.getProvider().equals(LocationManager.PASSIVE_PROVIDER))
                   {
                       actioncode = Integer.parseInt(getApplicationContext().getResources().getString(R.string.actioncode_automatic_passive),16);
                       //FIXME  sendGeoEventToServer()  ;                                      
                   }

                }                                                   

            } 
            else
            {
                Log.e("ASWIS=>sLTS()","Auto sending tries==0, Automatic location sending failed! Adding location to list...");                  
                GeoEvent myGeoEvent = new GeoEvent(location, actioncode, new  DeviceInformation(getApplicationContext()).getBatteryLevel());
                mySqlDataSource.InsertGeoEvent(myGeoEvent);

            }
        } 
        else 
        {

        }                   
}   

}

和清单中的警报:

<receiver
            android:name="com.commonsware.cwac.wakeful.AlarmReceiver"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.BATTERY_OKAY" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
            </intent-filter>
            <meta-data
                android:name="com.commonsware.cwac.wakeful"
                android:resource="@xml/wakeful" />
        </receiver>
相关问题