安卓 GPS 定位周期性问题

4
我希望创建一个应用程序,在早上9点到晚上9点之间每5分钟获取一次用户位置。现在我无法思考流程。我困惑的是:
  1. 我应该实现两个重复的闹钟管理器,一个用于每5分钟,另一个用于时间段吗?
  2. 还是要每5分钟触发一个闹钟,并检查它是否在时间段内,然后只运行位置服务并上传到服务器工作?
请给我建议和意见,如何以最佳方式在手机电池寿命和效率方面实现此目标。

1
在此之前每隔5分钟定位一次是个好主意吗?我不确定手机电池能否持续到晚上9点。 - Sanoop Surendran
@Sanoop 我知道你是对的。这不是一个好的做法,但这是客户要求的。 - young_08
嗨,最近谷歌更新了获取用户位置的API,使其更加高效。 https://android-developers.googleblog.com/2017/06/reduce-friction-with-new-location-apis.html 这可能会对您有所帮助。 - vijaypalod
4个回答

0

不应该使用Handler.postDelayed()来处理超过30秒的时间间隔,因为这可能会导致内存泄漏。开发一些策略 - 一个用于短时间间隔 - 少于30秒,使用Handler,另一个使用AlarmManager(用于更长的时间间隔)。


我可以使用Firebase作业调度程序,在早上9点启动服务,晚上9点停止吗? - young_08
我没有使用过Firebase的作业调度程序,但还有一件事情 - 如果您使用AlarmManager,则应该监听设备重启事件,因为重置设备会取消所有待处理的警报。 - Alex Shutov

0

0

你可以使用handler查询位置,可以像这样做

 Handler handler = new Handler();
 Runnable runnable = new Runnable() {
        public void run() {
            currentLocation = getCurrentUserLocation();
            handler.postDelayed(this, 1000*60*5);
        }
    }
 };
 handler.postDelayed(runnable, 1000*60*5);

如果要检查时间间隔是否在范围内,您可以为此任务设置闹钟管理器,

一旦达到时间限制,您需要通过以下方式删除处理程序回调:

handleLocation.removeCallbacksAndMessages(null);

是的,一个用于启用,另一个用于禁用。 - Sanoop Surendran

0

我在这里创建了一个服务,每隔1分钟提供当前位置。您可以根据自己的需求进行修改-

还要将其添加到gradle文件中-

compile 'com.google.android.gms:play-services:9.4.0'

LocationService.class

import android.Manifest;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.text.SimpleDateFormat;
import java.util.Date;

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
    protected static final String TAG = "location-updates";
    private static final long day = 24 * 60 * 60 * 1000;
    private static final long hours = 60 * 60 * 1000;
    private static final long minute = 60 * 1000;
    private static final long fiveSec = 5 * 1000;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate() {
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(minute);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setSmallestDisplacement(0);

        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }


    @Override
    public void onConnected(Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }


    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    }

    //Location Listener
    @Override
    public void onLocationChanged(final Location location) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String currentDateandTime = sdf.format(new Date());
        Log.e("Location ", location.getLatitude() + " " + location.getLongitude() + " " + currentDateandTime);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        boolean isGranted = false;
        for (int i = 0; i < grantResults.length; i++)
            if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION) && (grantResults[i] == PackageManager.PERMISSION_GRANTED))
                isGranted = true;
        if (isGranted) {
            startService(new Intent(this, LocationService.class));

        } else {

        }
    }
}

这对电池使用有什么影响?相比于设置AlarmManager每分钟触发并检查位置,这样做是否更省电? - Nikaoto
1
嗨@Nikaoto, 是的,它更有效率和省电,因为如果您使用闹钟管理器定期触发请求,它会始终在固定时间间隔内检查位置。 - PankajSharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接