Android 定期检索地理位置

Android 定期检索地理位置,android,geolocation,Android,Geolocation,我正在开发一个应用程序,应该每隔3分钟定期向用户发送地理位置信息。我正在阅读android文档,想知道是否需要在我拥有的每个活动/片段上创建LocationListener 我在想一个类似于观察者的东西,它与应用程序一起运行,就像一个“静默线程”,并将数据发送到我的服务。是否有类似的东西,或者我必须在每个地方实现LocationListener 提前感谢。我有一些实现具有相同的请求,还请记住,设备在定位时可能会失去连接,因此您可能会考虑在sqlite中实现保存位置。看起来是这样的: Wakefu

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

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


提前感谢。

我有一些实现具有相同的请求,还请记住,设备在定位时可能会失去连接,因此您可能会考虑在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);
    }

}
}

以及舱单中的警报:

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

为什么不在位置发生变化时发送呢?您可以设置一个WakefulIntentService,让它查询最新的位置对象,并每隔3天发送一次minutes@stark好主意。我已经在onLocationChanged上实现了它,看起来更好了,但我正在努力避免使用第三方库。。如果我这样做,我的“BaseActivity”上只有几行,这是一个很好的解决方案,但我试图避免使用第三方库,我不知道我是否真的需要AlarmManager。我已经创建了一个扩展的“master”活动,所以我将该位置的代码放在这个类中。它看起来不太好,但很有效:
<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>