【问题标题】:Receive GPS Location updates in background在后台接收 GPS 位置更新
【发布时间】:2014-10-05 02:06:54
【问题描述】:

我是 Android 的新手,是从 iOS 迁移过来的。我正在开发一个健身应用程序(4.3+)来计算用户的位置并跟踪它。一切都很好,除了当应用程序进入后台时,我停止接收位置更新。

我目前正在使用从 GPSManager 类到 UserFitness 类的 BroadcastReceiver。在 GPSManager 类中,我启动了 LocationManager 以及其他所有内容,包括启动位置更新。然后,每当有新的位置更新可用时,它就会被广播到 UserFitness 类,并在此处完成一些计算、存储并显示给用户。我研究过我需要为 LocationManager 实现一个服务以在后台工作,但我不确定如何为我当前的代码实现它。我所有的代码都在下面。

谁能告诉我如何根据我的代码在后台获取位置更新,以及这是否可能一次大约 4 小时而不系统破坏进程?如果系统确实破坏了它,可以做些什么来让进程尽快恢复到以前的状态?

谢谢!


代码

GPSManager.java

public class GPSManager{

private static final String TAG = "GPSManager";
public static final String ACTION_LOCATION = "com.fitnesstracker.ACTION_LOCATION";

private static GPSManager sGPSManager;
private Context mAppContext;
private LocationManager mLocationManager;
private Location mLastLocation;

private GPSManager (Context appContext,GpsStatus.Listener listen)
{
    mAppContext = appContext;
    mLocationManager = (LocationManager) mAppContext.getSystemService(Context.LOCATION_SERVICE);
    mLocationManager.addGpsStatusListener(listen);
}

public static GPSManager get (Context c,GpsStatus.Listener listen)
{
    if (sGPSManager == null)
    {
        //USE THE APPLICATION CONTEXT TO AVOID LEAKING ACTIVITIES
        sGPSManager = new GPSManager(c,listen);
    }
    return sGPSManager;
}

private PendingIntent getLocationPendingIntent (boolean shouldCreate)
{
    Intent broadcast = new Intent(ACTION_LOCATION);
    int flags = shouldCreate ? 0 : PendingIntent.FLAG_NO_CREATE;

    return PendingIntent.getBroadcast(mAppContext, 0, broadcast, flags);
}

public void startLocationUpdates()
{
    String provider = LocationManager.GPS_PROVIDER;

    //GET LAST KNOWN LOCATION AND BROADCAST IF THERE IS ONE

    mLastLocation = mLocationManager.getLastKnownLocation(provider);
    if (mLastLocation != null)
    {
        mLastLocation.setTime(System.currentTimeMillis());
        broadcastLocation(mLastLocation);
    }

    //START UPDATES FROM LOCATION MANAGER
    PendingIntent pi = getLocationPendingIntent(true);
    mLocationManager.requestLocationUpdates(provider,0,0,pi);
}

private void broadcastLocation (Location location)
{
    Intent broadcast = new Intent(ACTION_LOCATION);
    broadcast.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
    mAppContext.sendBroadcast(broadcast);
}

public void stopLocationUpdates()
{
    PendingIntent pi = getLocationPendingIntent(false);

    if (pi != null)
    {
        mLocationManager.removeUpdates(pi);
        pi.cancel();
    }
}
}

UserFitness.java

public class UserFitness extends Activity  {

private GPSManager mGPSManager;
private Location mLastLocation;
private boolean isGPSReady;
private float mLastLocationMillis;

private GpsStatus.Listener mGPSListener = new GpsStatus.Listener()
{
    public void onGpsStatusChanged(int event) {
        switch (event) {
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
             if (mLastLocation != null)

             isGPSReady = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 13000;

             if (isGPSReady) { // A fix has been acquired.
                calculateUserDistance()
            } else { // The fix has been lost.
                Toast.makeText(getApplicationContext(), "GPS Signal Fix Lost", Toast.LENGTH_SHORT).show();
            }
            break;
            case GpsStatus.GPS_EVENT_FIRST_FIX:

            isGPSReady = true;
            break;
        }
    }
};

private BroadcastReceiver mLocationReceiver = new LocationReceiver()
{
    @Override
    protected void onLocationReceived (Context context, Location loc)
    {
        mLastLocationMillis = SystemClock.elapsedRealtime();
        mLastLocation = loc;
        Log.d("OnLocationReceived",mLastLocation.toString());
    }

    protected void onProviderEnabledChanged (boolean enabled)
    {

    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fitness);
     mGPSManager = GPSManager.get(this,mGPSListener);
}

@Override
public void onStart()
{
    super.onStart();
    this.registerReceiver(mLocationReceiver, new IntentFilter(GPSManager.ACTION_LOCATION));
    mGPSManager.startLocationUpdates();
}

@Override
public void onStop()
{
    this.unregisterReceiver(mLocationReceiver);
    super.onStop();
}

/* private void calculateUserDistance() */

【问题讨论】:

    标签: java android


    【解决方案1】:

    哦,不!这是处理位置更新的旧方法!首先,你要熟悉this guideline。 本指南描述了使用LocationClient 的位置跟踪策略。

    请注意,还有更新的跟踪当前位置的方法 - 将 GoogleApiClientLocationServices 结合使用,但由于缺乏适当的文档,您现在可以忽略它:(

    返回 LocationClient - 有两种接收位置更新的方式:

    如果您想创建一个健身应用 - 您一定会想看看ActivityRecognition API

    【讨论】:

    • 非常感谢您的快速回复。我很失望听到他们不赞成我实施事物的方式。我正在关注开发人员书籍“Android 编程:大书呆子牧场指南”。我马上去看看LocationClient
    • 是的.. 越早越好 - LocationClient 在电池方面做得更好,所以它可能对您的应用至关重要
    • 听起来完全符合我的需要。我会接受你的回答。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多